Skip to content
This repository has been archived by the owner on Oct 8, 2020. It is now read-only.

Model updates

danielwertheim edited this page Jan 17, 2012 · 12 revisions

Since SisoDb stores the object graph representation as JSON and as a flattened object in the Indexes-table using key-values in the Indexes table, you could of course update the values in the Indexes-table using T-SQL and also try to update the JSON member using T-SQL, but sometimes you might want to perform more advances updates, and then you do basically do have to re-save the structures, and there's a method to facilitate this for you.

Simple changes - adding and dropping new members

Whenever a new property in the graph is introduced, the values will be inserted in the Indexes-table upon the next insert and in the Uniques-table as well if you have marked them as unique.

If you remove a property in the graph, the values from the Indexes-table and the Uniques-table will be deleted. The value will still reside in the JSON-structure, until the next time the item is updated.

Supported complex changes

There's functionality to assist you with schema changes of more complex nature, e.g:

  • Rename structure
  • Rename properties
  • Split one property to several
  • and more...

To do this, you use:

db.CreateStructureSetMigrator().Migrate<TOld, TNew>(Func<TOld, TNew, StructureSetMigratorStatuses> migrator);

As long as the underlying provider supports it (e.g Sql2008, SqlCe4) all changes are performed within transactions, hence datachanges can be rollbacked. All items are read back as json and then deserialized to both the TOld and TNew items which then are injected to a modifier func, where you perform the changes and return a status indicating what you want todo with the structure.

StructureSetMigratorStatuses

The modifier can return three different values:

  • Keep: Indicates that you want to keep the structure and the new-structure will be persisted with the same id as the old.
  • Trash: Indicates that your are no longer interested in keeping the structure, hence it will be deleted.
  • Abort: Abort and rollback the process.

Tips of how to deal with the old entities

You do need to have an entity in your model that is compatible with the Old entity. This old entity needs to be there for reading up entities from the old structure hence it need to be compatible with the json structure (at least the members you want to keep)

Store the old model items in a project used only for updating a production environment. E.g in a console app and then add a reference to the new model to this app and use this application to apply the changes.

There will be a dynamic structure available in the future, which you then can use for performing model updates without the need of the old model.

Rename structure

If the new structure is compatible with the Json you don't have to provide any manual mappings just return StructureSetMigratorStatuses.Keep so that SisoDb will insert the new item in the new structureset.

(oldItem, newItem) => StructureSetMigratorStatuses.Keep;

Rename properties

The TNew item has the new property and you will need to map it manually:

(oldItem, newItem) =>
{
    newItem.NewProperty = oldItem.OldPropery;
    return StructureSetMigratorStatuses.Keep;
}

Split one property to several

I'll just let the example speak for it self.

New model

public class Person //Change: Rename
{
    public Guid Id { get; set; }
    public string Name { get; set; } //Change: Split
    public string Address { get; set; } //Change: Split
    public string HairColor { get; set; } //Change: Drop
}

Old model

public class SalesPerson
{
    public Guid Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public Address Office { get; set; }

    public SalesPerson()
    {
        Office = new Address();
    }
}

public class Address
{
    public string Street { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
}

Given

new Person
{
    Name = "Daniel Wertheim",
    Address = "The Street 1\r\n12345\r\nThe City",
    HairColor = "Black"
};

We want

new SalesPerson
{
    Firstname = "Daniel",
    Lastname = "Wertheim",
    Office = new Address
    {
        Street = "The Street 1",
        Zip = "12345",
        City = "The City"
    }
};

How-to do it

db.CreateStructureSetMigrator().Migrate<Person, SalesPerson>(
(p, sp) =>
{
    var names = p.Name.Split(' ');
    sp.Firstname = names[0];
    sp.Lastname = names[1];

    var address = p.Address
        .Split(new[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries);

    sp.Office.Street = address[0];
    sp.Office.Zip = address[1];
    sp.Office.City = address[2];

    return StructureSetMigratorStatuses.Keep;
});
Clone this wiki locally