IT:AD:Code First:Initialization
Summary
Notes
//FIX: Initializer has to be same type of DbContext as DbContext we want (using a generic DbContext, //or any DbContext that is not exact same match as DbContext used for first call to Db, will cause //the Seed method to never be called: //Does not work: Database.SetInitializer(_unitTestDatabaseInitializer);
IDatabaseInitializer
- When the db is first created, it creates a Db table called EdmMetadata.
- Schema is simple: [Id | ModelHash], with a clustered index on Id. That appears to be it.
- Changes to the entity schema will cause:
The model backing the 'TestContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
There are several solutions:
Manually update the db schema
??? How can this work? Delete and re run the app, which will create the db, and seed it. Enable a development environment feature that updates the db automatically, By Setting the Initialization Strategy: DEFAULT: DropCreateDatabaseOnlyIfNotExists According to (http://bit.ly/u7a0yG) [http://bit.ly/u7a0yG] can be set to null.Code:
<
sxh csharp>
public class AppDbContext {
public AppDbContext() { SetDbContextInitializer(); } private void SetDbContextInitializer(){ if (_environmentService.GetEnvironmentVariable("isDebugStation") == "true"){ //You want to be extra careful that only Dev stations can potentially dropped dbs: //Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<TestContext>()); else //WIth no strategy, it won't check the EdmMetaData table is there or not. //Just will try, and fail as normal... //Then one can deploy as one should? Database.SetInitializer<TestContext>(null); //or: Database.SetInitializer(new XAct.Data.EF.CodeFirst.NullDatabaseInitializer<TestContext>()); endif }
}
public class NullDatabaseInitializer<TContext> : IDatabaseInitializer<TContext> where TContext: DbContext { public void InitializeDatabase(TContext context){} protected virtual void Seed(TContext context){} }
</sxh>
Dealing with Multiple databases
Database.SetInitializer(new MyInitializer) can be invoked:
- in bootstrapper
- or within Constructor of DbContext.
- See: Ref:SO