Revit Extensible Storage Schema Migration

Revit Extensible Storage Schema Migration

Migrations are important part of web application development. You never know what fields will you exactly need in your database, and there are many ways to easy create migrations or migrate Database for Web development.

Extensible Storage Schemas in Revit API provides as a functionality a little bit similar to database: every element can become a 'row' (entity) in a 'database' (schema), and you can store there a lot of information. It is a really powerful instrument to store the data and hide it from the user.

Schema problems

However, while development of tool for Autodesk Revit, our team faced some problems with Schema. This class, as it created in Revit API is not flexible at all. You can create any schema for you needs, but once created, there are no ways to change the schema. You can only create a new one with new Guid, but what should you do with old files with old schemas? Your tool can create a new schema, but all the data from old schema will be ignored.

Another problem is API for Schema and Entity. It is not very convinient, you should always write 3-5 lines of code to change one field of entity. And you must keep in mind correct field name and field type which can cause an error:

var schema = Schema.Lookup(schemaGuid);
var entity = _element.GetEntity(schema);
entity.Set<string>("fieldName", value);
_element.SetEntity(entity);        

And if you have 50 fields, you should repeat this 50 times.

New approach

We wanted to fix the problem with schema flexibility and lose of data while changing schemas. So Atomatiq team created a special library to manage schemas:

Atomatiq.SchemaMigrations.

We wanted to simplify work with schemas and make it as easy as working with Entity Framework. So our approach is very similar to it:

  1. Define a Model to store in Schema.
  2. Define a SchemaContext with SchemaSets. Every SchemaSet is a collection of your Models.
  3. Run special Migration Generator Tool created by us.
  4. In your code, create class DatabaseConnection<TModel>() from the package. To Save data, just use SaveObject method with your Model class. To load data from entity, use LoadObject method. They will save/load all of your data in one line of code.

var connection = new DatabaseConnection<Person>(instance);
var person = new Person
{
    Id = 69,                                                     // one line — one schema field
    Name = "Mirko",
    Surname = "Petrovi?",
    Occupation = "Software development",
    Scores = new Dictionary<string, int>       // dictionary field
    {
        { "Scores", 1 }
    },
    Hobbies = ["Sports"]                                  // list field
};
connection.SaveObject(person);        

Every property of your model will become a new Field in Schema. So you do not need to use magic string for every field, just use properties of your model.

5. If you need to change a Model, just change it and run Migration Generator. It will create a new migration, that will be applied right after first DatabaseConnection call. All the data in existed schemas will be brought to the newly created actual one.

That's it, now working with Extensible Storage became much easier.

Example of usage

We have already used this library for our clients. Before this, we had a problem with a family creation tool — it stored data in schema. But when we added a new feature, new schema applied, and existing families looks like they do not have data inside it (new entity for them did not seed). After creation of this library, the problem goes away and we can change our schema in any way that we want — all the data transfers correctly.

Conclusion

You can find open-source code for this library in our Github repository. There you will find more detailed readme instructions for installation and usage. Do not forget to put star to the repo if you find it helpful. If you find any bugs, please contact the library developer. Happy coding!

Julio Polo

BIM Software Developer | Revit API | C# | Autodesk Platform Services | Dynamo | Python | IFC.js

1 个月

Looking forward to using this! Thanks a lot

要查看或添加评论,请登录

社区洞察

其他会员也浏览了