What is the Need of Database Initializer?
The job of database initializer is to create the database and the specified tables. When a DbContext
type is used to access database for the first time, then the database initializer is called.
The Database.SetInitializer()
method does this initialization operation. The following is the method signature (see documentation):
public static void SetInitializer(
IDatabaseInitializer strategy
)
where TContext : DbContext
The SetInitializer()
method takes a parameter of IDatabaseInitializer<TContext>
where the TContext
is of DbContext
type. DbContext
is the lightweight version of ObjectContext
.
The IDatabaseInitializer<TContext>
has three implementations:
CreateDatabaseIfNotExists<TContext>
, DropCreateDatabaseAlways<TContext>
, DropCreateDatabaseIfModelChanges<TContext>
Explanation
CreateDatabaseIfNotExists<TContext>
: This is the default option. For the first time when the application runs, the Entity Framework Code First creates database if it does not exist. If your database already exists and you have made some modification to the model and now you are running the application again, then you will get an exception of type InvalidOperationException
. DropCreateDatabaseAlways<TContext>
: As the name suggests, it always drops and recreates the database when the application runs for the first time. It deletes all the tables as the database is dropped. DropCreateDatabaseIfModelChanges<TContext>
: It drops and recreates the databases only when there are some changes or modifications in the model. Code First compares the version of in memory model with what is stored in the _MigrationHistory
table to know whether the Model
is changed or not.
Note
If you will call the Initialize()
method immediately after creating a context instance, then the database will be created immediately instead of waiting until the context is used for the first time.
using (var context = new EducationContext())
{
context.Database.Initialize(false);
}
The Initialize()
method takes a boolean parameter to decide whether the initialization process should re-run. If you will pass false
, then the initialization process will skip if it has already executed. A value of true
will initialize the database again even if it was already initialized. This is useful if a database is deleted while an application is running and it requires the database to be reinitialized.
If you use an existing database with Code First, you may not want to execute any initialization logic at all. You can disable the database initialization process altogether by passing null
to SetInitializer()
method.
Database.SetInitializer<EducationContext>(null);
Custom Database Initialization
You can create your custom IDatabaseInitializer<TContext>
by implementing any of the above three options as follows:
public class MyDbInitializer : DropCreateDatabaseAlways<EducationContext>
{
protected override void Seed(EducationContext context)
{
var student1 = new Student { Name = "Name 1" };
var student2 = new Student { Name = "Name 2" };
context.Students.Add(student1);
context.Students.Add(student2);
context.SaveChanges();
}
}
Database.SetInitializer<EducationContext>(new MyDbInitializer());
The Seed()
method is used when you want to insert some initial values to some tables. For example, if you have a look up table, then you can insert the look up data by this Seed(TContext)
method. This Seed(TContext)
method will execute after the database tables are created.
Where to Keep Database.SetInitializer() Method?
The Database.SetInitializer()
method should be kept before the Context
object is initialized. In ASP.NET web application, the best place will be in Application_Start()
event of Global.asax file.
History
- 3rd September, 2014: Initial version