As the data schema of an applicaion changes, the underlying program must check to see if the it is accessing the correct schema. If not, it could attempt to write to a field that has either been deleted, renamed, or not yet in the data store. One way to accomplish this is to keep a schema version in the data store and an expected schema version in the application. If they match, the application continues; if not, the application notifies the user and exits. SchemaVersion is incorporated in the Xpo.UpdateSchema to help manage this process.

A class must implement the ISchemaVersion for Xpo.UpdateSchema to process the update. SchemaVersionBase, an abstract base class, provides most of the functionality required. SchemaVersionBase is a generic class so that a wide variety of types can be used for the version value. Testing has been done for both int and string types, but other simple types will most likely work as well. SchemaVersionBase also allows tracking of when the version was updated in the data store.

First, create a XPObjectBase descendent to store the schema version. The SchemaVersionBase is designed to handle as a single record table with the schema version in a single field. If there are more than one records in this table an exception will be thrown.

    /// 
    /// DataStoreProperties is an XPO object to store 
    /// properties of the data store.
    /// 
    public class DataStoreProperties : XPObject
    {
        private int schemaVersion;
        private DateTime schemaVersionUpdated;

        /// 
        /// Initializes a new instance of the
        ///  class.
        /// 
        /// The session used to create the
        /// instance.
        public DataStoreProperties(Session session)
            : base(session) { }

        /// 
        /// Gets or sets the schema version.
        /// 
        /// The schema version.
        public int SchemaVersion
        {
            get { return schemaVersion; }
            set { SetPropertyValue("SchemaVersion",
                ref schemaVersion, value); }
        }

        /// 
        /// Gets or sets the DateTime the schema version
        /// was updated.
        /// 
        /// The DateTime the schema version was
        /// updated.
        public DateTime SchemaVersionUpdated
        {
            get { return schemaVersionUpdated; }
            set { SetPropertyValue("SchemaVersionUpdated",
                ref schemaVersionUpdated, value); }
        }
    }

Next, create a descendent of SchemaVersionBase passing in the type of data to use the schema version. The following implementation stores the version as an integer.

Example of an concrete ISchemaVersion implementation using SchemaVersionBase:

    /// 
    /// The object used to update the schema version. Also
    /// provides information about the schema version.
    /// 
    public class SchemaVersionInt : SchemaVersionBase
    {
        /// 
        /// Increment the requiredSchemaVersion value for
        /// each version of the schema
        /// 
        private int requiredSchemaVersion = 1;

        /// 
        /// Initializes a new instance of the
        ///  class.
        /// 
        /// The XPO data layer to use
        /// when accessing the data store.
        public SchemaVersionInt(IDataLayer dataLayer)
            : base(dataLayer) { }

        /// 
        /// Gets the property name of the DateTime that the
        /// SchemaVersion was updated. If this is null or empty,
        /// no attempt will be made to store the updated time.
        /// 
        /// 
        /// The property name of the DateTime that the
        /// SchemaVersion was updated.
        /// 
        public override string DateVersionUpdatedPropertyName
        { 
            get { return "SchemaVersionUpdated"; } 
        }

        /// 
        /// Gets the name of the SchemaVersion property in the
        /// data store.
        /// 
        /// The name of the SchemaVersion property.
        public override string VersionPropertyName
        {
            get { return "SchemaVersion"; }
        }

        /// 
        /// Gets the type of the XPO object from the data store.
        /// This must be a descendant of XPObjectBase.
        /// 
        /// The type of the XPO object.
        public override Type XpoObjectType
        {
            get { return typeof(DataStoreProperties); }
        }

        /// 
        /// Gets the required schema version (as an object).
        /// This value is what the schema version should be
        /// for the current version of the application.
        /// 
        /// 
        /// The value (as an object) of the required data
        /// source schema version.
        /// 
        public override int GetRequiredSchemaVersion()
        { 
            return requiredSchemaVersion;
        }
    }

In this example some key elements are:

  • The property XpoObjectType is set to the DataStoreProperties class. This links this class with the SchemaVersion implementation.
  • The property VersionPropertyName is set to the name of the property which holds the actual schema version; in this case SchemaVersion.
  • Optionally the property which holds the DateTime that the SchemaVersion was updated can be set. In this case it is set to SchemaVersionUpdated.
  • Finally, the actual value of the SchemaVersion is stored as a const in the field member requiredSchemaVersion. This value is manually changed each time the schema is updated on the users machine.

To use the SchemaVersion instantiate the UpdateSchema object and pass in your ISchemaVersion implementation

    using(UpdateSchema updateSchema = new UpdateSchema("myConnectionString",
        new SchemaVersionInt()))
    {
    }

 

Back to task-based help.