Reputation: 7757
I have a DbContext in an assembly that is shared between two service projects. I have both projects set to start for debugging in Visual Studio. This creates a race condition where the DatabaseInitializer
in each service tries to update the database on startup.
To prevent this, I modified my DbContext
as follows so as to prevent the DatabaseIntializer
from being automatically registered.
public EntityContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<EntityContext>(null);
}
}
I wanted to disable the DatabaseInitializer
inside the DbContext
itself so that I would not have to duplicate that SetInitializer()
call in every project that happened to reference my DbContext
, and based on what I'd read, overriding OnModelCreating()
seemed to be the way to do it.
That prevents the DatabaseInitializer
from running automatically, but I wanted to create a separate project that I could run manually in order to update the database. So I did something like the following:
static void Main(string[] args)
{
Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>());
new EntityContext().Database.Initialize(true);
}
The problem is that this doesn't seem to work - the null initializer set in the OnModelCreating()
method apparently overrides anything that I specify in any other call to SetInitializer()
. Even if I move the SetIntializer(null)
call to a static constructor of the EntityContext
class so as to guarantee it is called first it still doesn't work. The only way it works is if I manually call the initializer as follows:
static void Main(string[] args)
{
new CreateDatabaseIfNotExists<EntityContext>()
.InitializeDatabase(new EntityContext());
}
But calling the DatabaseInitializer.InitializeDatabase()
directly does not seem right, as the Entity Framework infrastructure is supposed to call that.
Is this a bug in EF Code First? What is the "correct" way to go about this?
UPDATE: I decided that manually creating a database script with the Update-Database
Package Manager Console command is a better solution than this kludgey project that tries to update the database programmatically.
Upvotes: 1
Views: 2679
Reputation: 7523
This should work so long as the call to set the initializer is made after the call to disable the initializer. Neither OnModelCreating or the static EntityContext initializer do that in your case. The static initializer will only be called when you use EntityContext for the first time, which in your example is not until after the call to SetInitializer.
You could consider forcing a call to the static initializer before making the SetInitializer call. For example, this should work:
using (var context = new EntityContext())
{
Database.SetInitializer(new CreateDatabaseIfNotExists<EntityContext>());
context.Database.Initialize(true);
}
Upvotes: 1