Best Practices on using the MigrationBase namespace

I poured over the database documentation for v13, noting what appears to be a move away from EntityFramework. I noticed that the detail and best practices is rather scant. I have also combed through the Umbraco.Cms.Infrastructure.Migrations namespaces for clues.

I am new to Umbraco, but not new to CMS or ASP.NET. I am working with a semi-deployed environment with serious content and schema already in play and am trying to make sure I don’t munge up what I already have.

I am adding two tables, one lookup, one for captured data. I am familiar with the controller end of this implementation. I am looking for guidance on migration composition.

Is there a guide out there for answering questions related to:

When implementing a custom table, is there a way to implement custom tables in a new database schema (other than SQL Server’s default ‘dbo’?)
When implementing a concrete version of MigrationBase, should this class exist for the purpose of one single table or is it okay to bundle up an entire multi-table creation in this instance?
One of my tables needs to be hydrated with pre-existing look up data. Is there a preferred method? (I know of Execute.Sql( ) and Insert.IntoTable( ).)
I thought I saw a Migration attribute that decorated classes with a version number. Did that get deprecated?

I think I have a good sense of how to integrate this data with custom controllers and views, even when working with uSkinned. Just trying to see if I am going about this the wrong way.

Any help would be appreciated.

Hi Ian,

I can’t talk on best practices, but I can offer an example of how I’ve personally used Umbraco’s PackageMigrationPlan to add a custom tables using NPoco:

Here’s a link to the migration plan of my package, although it’s a very simple one, having only one migration step:

I’ve used the same technique in my client projects when adding custom tables.


As for your questions, I think I can answer two of them:

When implementing a concrete version of MigrationBase, should this class exist for the purpose of one single table or is it okay to bundle up an entire multi-table creation in this instance?

Personally, I have used a single MigrationBase implementation to manage multiple tables.
For example, this is what I have in a client’s project to manage custom Member tables:

    public class CustomMemberTablesMigrationPlan : PackageMigrationPlan
    {
        public MigrationPlan() : base("CustomMemberTables") { }

        public override bool IgnoreCurrentState => false;

        protected override void DefinePlan()
        {
            From(string.Empty);
            To<InitialMemberTablesMigration>("initial-member-custom-tables");
            To<IncreaseAnswerVarcharSize>("increase-answer-size");
            To<AddActivityLike>("add-member-activity-like");
            To<AddDescriptionToFavouriteResource>("add-description-to-member-fav-resource");
            To<UpdateFileUploadTable>("update-file-upload-table");
        }
    }

And the initial migration step creates all of the tables:

    internal class InitialMemberTablesMigration : MigrationBase
    {
        protected override void Migrate()
        {
            if (TableExists("_MemberActivityStep") == false)
            {
                Create.Table<MemberActivityStepPoco>().Do();
            }

            if (TableExists("_MemberAnswer") == false)
            {
                Create.Table<MemberAnswerPoco>().Do();
            }

            if (TableExists("_MemberFavouriteResource") == false)
            {
                Create.Table<MemberFavouriteResourcePoco>().Do();
            }

            if (TableExists("_MemberFileUpload") == false)
            {
                Create.Table<MemberFileUploadPoco>().Do();
            }

            if (TableExists("_MemberProgrammeQuiz") == false)
            {
                Create.Table<MemberProgrammeQuizPoco>().Do();
            }

            if (TableExists("_MemberProgrammeSubChapter") == false)
            {
                Create.Table<MemberProgrammeSubChapterPoco>().Do();
            }

        }
    }

The subsequent migration steps (MigrationBase implementations) where then added after the initial development, either during bugfixes or RFCs.

I tend to create a single PackageMigrationPlan per “feature” that requires custom tables.

No idea if this is the best way to do it, it’s just how me and my team have done it.

One of my tables needs to be hydrated with pre-existing look up data. Is there a preferred method? (I know of Execute.Sql( ) and Insert.IntoTable( ).)

You should be fine using whichever method suits your project/team.


Also, it’s worth noting that Umbraco has recently introduced the ability to use Entity Framework for database migrations instead of NPoco:

I hope that helps :slight_smile:

1 Like

Since somewhere around Umbraco 12, Umbraco supports EntityFramework out of the box. Umbraco itself is not yet on EntityFramework, but that’s a goal for the future (although a monumental task). You can use Entity Framework migrations that work really well. I never use NPoco for database migrations, just EF. See the docs here:

Edit: didn’t see that Owain already mentioned it :slight_smile:

1 Like