Easy flexible data saving options

I originally used SQLCE starting with LINQ to SQL and then moved to Entity Framework, but SQLCE seems to be too inflexible. (Right now I can't even drop the table to recreate it because it says I can't delete the PrimaryKeyA because it is referenced by the PrimaryKeyA ... so I'm not very sure if I can modify it later) / p>

I need the flexibility that the application will be released over many iterations and the data should be able to change quite easily. Newer versions of the application should be able to read data from older versions, either directly or by conversion.

It should be lightweight to deploy, less than 10MB, but up to 5 is preferred. The user will (should) not modify data outside of the application, and they will not need to know or care about how the data is stored.

High performance is not a problem, it will just be one user data. Right now I'm tempted to say just go with XML in order to use LINQ to XML. But I'm wondering if there are any other suggestions. I would like something that easily translates to and from regular objects, would XML serialization be used?

I guess I'm looking for an easy way to save objects that can be easily updated to newer versions with object changes. Performance is not a big issue, but it should be at least acceptable for small / medium data volumes. (Mostly an electronic form of a cook's book for one user's recipes)

+1


a source to share


3 answers


I would suggest that the XML route you are considering might be a sane idea. Although more verbose than binary serialization, it is easier to debug if needed; and shrinks nicely (on the fly) if less disk usage is required.



+1


a source


There is always binary serialization in the file. It's not sexy, but it works and it doesn't require any third party tools or software. Just make sure you precede each data grouping with a version number (usually called a schema number). This will ease headaches on the road when you change the data model.

In an OOP setup, usually every object that needs to be saved has a Serialize () method that takes a direction parameter (save versus load) and an object that represents the binary. When writing, you just need to make sure that every object gets serialized. As you read, you need to create objects as you go. This process is often facilitated by a container that knows how to serialize an object.

The conversion is handled on the fly by various Serialize () methods. For example, if an object that is currently in Schema version 5 collides with data that was written using Schema 4, it will know how to deal with it.

However, if you need SQL like the query capabilities, this may not be the best option. This works best when you read through all the data.

Example:



Say you are a Foo class that has two member variables that you want to serialize:

class Foo
{
public:
  const unsigned int SCHEMA = 1;
  int i;
  double d;

  void Serialize(bool bSaving, CBinaryFile file)
  {
    if (bSaving)
    {
      // Serialize everything out
      file << SCHEMA << i << d;
    }
    else
    {
      // Read in the schema number first
      unsigned int nSchema;
      file >> nSchema;

      // Validate the schema number
      if (nSchema > SCHEMA)
      {
        // We're reading in data that was written with a newer version of the program
        // Since we don't know how to handle that let error out
        throw exception;
      }

      // Read everything in
      file >> i >> d;
    }
  }
}

      

Now let's say a year later, you add another member to Foo. You would handle it like this:

class Foo
{
public:
  const unsigned int SCHEMA = 2;
  int i;
  double d;
  string s;

  void Serialize(bool bSaving, CBinaryFile file)
  {
    if (bSaving)
    {
      // Serialize everything out
      file << SCHEMA << i << d << s;
    }
    else
    {
      // Read in the schema number first
      unsigned int nSchema;
      file >> nSchema;

      // Validate the schema number
      if (nSchema > SCHEMA)
      {
        // We're reading in data that was written with a newer version of the program
        // Since we don't know how to handle that let error out
        throw exception;
      }

      // Read everything in
      file >> i >> d;
      if (nSchema > 1)
        file >> s;
    }
  }
}

      

As long as you complete all the Scheme numbers on the fly, the conversion is straight forward.

+2


a source


I suggest using System.Data.SQLite . It gives you simple, high performance SQL through ADO.net interfaces and lightweight. It is also reasonably well documented and fixes the problem easily with the sqlite.exe command line client and other tools. One of the big upsides for SQLite is that it has relatively fluent typing, so you don't have to spend a lot of time using schemas.

I can't tell if LINQ is supported, but it's pretty good.

+2


a source







All Articles