5

I'm building an extensible custom CMS solution where I have a parent DbContext named CmsDbContext with the entities for CMS tables, eg: Users table. CmsDbContext has automatic migrations enabled. I want allow the final user inherit from CmsDbContext in order to create custom extra tables/entities, by adding/mapping DbSet properties and custom POCO's.

The Cms needs that his CmsDbContext get initialized in PreStart, before the initialization of derived DbContext. So far so good, when I initialize CmsDbContext the tables are created sucessfully. When I initialize the derived DbContext e.g. CustomCmsDbContext, the extra tables are created successfully. But when the Web application is restarted, the migration process of CmsDbContext erase the tables that isn't owned by the context, and the tables for the inherited CustomDbContext are recreated.

I Know that it's possible to create multiple not related DbContexts with automatic migrations enabled within the same database, because of the ContextKey property of DbMigrationsConfiguration will. But I need inheritance here in order to allow the CustomCmsDbContext context make queries against existing tables mapped by CmsDbContext, so both contexts behaves like one DbContext, with migrations enabled.

So we know the problem is that the parent DbContext deletes tables of the child DbContext during migration process, and the child DbContext recreates the missing tables during migration process.

How to avoid migrations from deleting tables that are not owned by DbContext ?

Here is the pseudo code:

public class CmsDbContext: DbContext {

    static CmdDbContext() {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<CmsDbContext, Migrations.CmsDbContextConfiguration>());
    }

    public DbSet<User> Users { get; set; }
}


public class CustomCmdDbContext: CmsDbContext {

    static CustomCmdDbContext() {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<CustomCmdDbContext, Migrations.CustomCmdDbContext>());
    }
    public DbSet<CustomEntity> CustomEntities { get; set; }
}
3
  • As best I know EF migrations simply are not designed to behave this way. I'd be interested to hear otherwise but I'm doubtful. Commented Apr 8, 2014 at 16:42
  • The approach you can take is break you're thinking into two parts: (1) how you interact with the database and (2) how you migrate, the database schema/data over time. It is OK to have multiple data contexts interact with the same database tables, but as you've discovered EF gets tripped up on multiple migrations that share tables. What I do is create a single "MigrationsDbContext" that may implement multiple interfaces, and then as many data db contexts as are needed that implement those interfaces. I'm sure this isn't the modular system you want...I just don't think what you want is supported Commented Apr 8, 2014 at 16:51
  • The idea of interfaces could solve the problem, but the problem is that the final "user" (a programmer) will not change the Cms code, instead, he will write new code into a separated library to extend the Cms as a plugin, so the base core will not know about his code. Commented Apr 8, 2014 at 17:55

1 Answer 1

5

This blog post from Rowan Miller descripes a very similar scenario: Let the customer add/edit user definied columns or tables to the context.

Sign up to request clarification or add additional context in comments.

1 Comment

Very good blog post. I will soon check it out and see if something from that post fits into my needs. Thanks for sharing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.