Version Checking

Apr 26, 2011 at 9:25 PM

I am using MEF to stitch together a list of Tables that are handed to Sterling. This is working very well, and I'm quite happy with it.

However, if one of my types changes I get some ugly errors when I try to access the tables for that type. To try to fix that, I'm taking the below approach. At app startup, after the MEF composistion is done, I'm doing:

  1. Calling GetTableDefinitions() on my sterling database.
  2. For Each table in TableDefinitions
  3.    var items = table.Query()
  4.     If items.Count > 0 then
  5.         myItem = item[0].LazyValue.Value
  6. Next

If an exception happens on line 5 I assume my DB is out of data and needs to be recreated.

I'm pretty sure this method is sub-optimal, and would love to hear about a better approach.


The actual code i'm using to do this is shown here:

       private static bool ValidateDatabase()
            // This method iterates over every table in the database and verifies that
            // the types in the database can be serialized. 
            // In effect, this gives us a versioning scenario. If a given table can't
            // be properly serialized it means the database is out of data and needs
            // to be rebuilt. 

            var tableDefinitions = LocalCache.Current.GetTableDefinitions();
            foreach (var tableDef in tableDefinitions)
                Type tableType = tableDef.TableType;
                Type keyType = tableDef.KeyType;

                var method = typeof(DevportalDatabase).GetMethod("Query", Type.EmptyTypes);
                    // Essentially this calls: LocalCache.Current.Query<tableType,keyType>() 
                    var generic = method.MakeGenericMethod(tableType, keyType);
                    var results = generic.Invoke(LocalCache.Current, null);

                    // the return value is a List<T>, which can be cast to a regular IList. 
                    IList resultsList = (IList)results;

                    if (resultsList.Count > 0)
                        var x = resultsList[0];
                        PropertyInfo y = x.GetType().UnderlyingSystemType.GetProperty("LazyValue");

                        // This returns a System.Lazy<tableType>
                        var z = y.GetValue(x, Type.EmptyTypes);

                        var alpha = z.GetType().GetProperty("Value");

                        // This should be of type 'tableType'
                        // Note: IF the type has changed for some reason this will throw
                        // a serialization exception. 
                        var beta = alpha.GetValue(z, Type.EmptyTypes);                                                
                catch (Exception)
                    return false;

            return true;

Chris Mullins

Apr 26, 2011 at 9:33 PM

This will likely be fixed by 1.5 RTM. Right now the isolated storage driver maintains an ordinal list of types and uses that to save them (i.e. first type is saved to slot 0, second to slot 1, etc.). Obviouslly, if you then omit or change the order of a type, the ordinals are off and it is looking at the wrong data. Because we now have a true separation via the driver architecture (and this should not be happening in the in-memory model by the way) the tables should save regardless of when defined ... that's the last update, I'm just trying to figure out what I want to do. Likely I'll just use the table type name and go from there, and then the problem should go away. I'll keep you posted.

Apr 26, 2011 at 9:39 PM

The idea here is slightly different - I'm not reporting a bug here. Quiet the opposite! :-)


1.  I have a bunch of data stored in my Sterling DB.

2. When all the XAPs are downloaded and MEF runs, I have some new versions of old types that are in the DB. (e.g. v1 'Name' has First / Last, and now v2 'Name' has First / Middle / Last.)

3. When I try to read the Databae, I need to know that my types, and the types in the DB, are a different version.

When I detect a different verison, I just blow away the entire DB and recreate it.

The "How best do I detect the types are a different version" is really my question... :-)

Chris Mullins