Multiple Context EF Initializer for the Same Database

I have an existing SQL database application that was encoded using the first database model (I create an EDMX file every time I have a schema change).

Additional development was done (Windows services that support the source application), which uses EF POCO / DbContext as the data layer instead of the EF EDMX file. Initialization parameters were never configured in DbContexts, but they never changed the database, because DbSet objects always corresponded to tables.

Now I have written a separate application that uses the existing database, but only its own new tables, which it creates using the EF initializer. I thought it would be great to use EF Code First to manage these new tables. Everything works fine when I first run the application, but now I get this error from some of my original EF POCO DbContexts (which never used an initializer).

The model supporting the "ServerContext" context has changed since the database was created. Consider using First Code Migrations to update the database

After some research, I found that EF compares the hash of its schema with some stored hash on the sql server. This value does not exist until the context actually used the initializer in the database (in my case, until the last application added its table).

Now my other DbContexts throw an error when they read an existing hash value and do not match its own. An EF connection using EDMX has no errors.

It seems like a solution would be to put this line in protected override void OnModelCreating(DbModelBuilder modelBuilder) in all DbContexts experiencing the problem

 Database.SetInitializer<NameOfThisContext>(null); 

But what if later I want to write another application and create my own tables again using EF Code, now I can never reconcile the hash between this theoretical and newer context and what is causing now.

Is there a way to clear the hash that stores EF in the database? Is EF smart enough to only modify tables that exist as DbSet in the current context? Any ideas were appreciated.

+4
source share
2 answers

What version of EF are you using? EF Code First used to store the SSDL hash in the EdmMetadata table. Then, in the .NET Framework 4.3, the thing changed a bit, and the EdmMetadata table was replaced by the __MigrationsHistory table (see this blog post for more details), But it seems to me that you really care about multi-user migrations , where you can have multiple contexts, using the same database. This feature was introduced in EF6 - (currently the version of Aplpha2 is publicly available) Also note that the EdmMetadata / __ MigrationHistory tables are CodeFirst specific. If you use the constructor (Model First / Database first), no additional information is stored in the database, and the EF model is not checked to see if it matches the database. This can lead to heavy debugging and / or data corruption.

+1
source

Yes, a limited database context is really good practice. for example, a base context class, to use a common database connection, each subclass uses Database.SetInitializer (zero); as you think.

Then go ahead and have 1 large context that has a “database view”, and this context is responsible for all migrations and ONLY this shoudl context does this. The only source of truth.

Having multiple contexts responsible for database migration is a nightmare, I don’t think you decide. Messing with system entries created using the first code transactions can only end in tears.

It is this theme that you are describing that I saw in the video of A Julie Lerman. Her proposed solution was the only “Migration” context, and then used many contexts of a limited border.

If you have a multiple point account: http://pluralsight.com/training/players/PsodPlayer?author=julie-lerman&name=efarchitecture-m2-boundedcontext&mode=live&clip=11&course=efarchitecture

+4
source

All Articles