Inititializing the DbContext

This is part of a series of posts regarding the new Entity Framework 4 Code First Framework.

In my last post I showed the simplest EF 4Code First demonstration. I’m going to flesh the example out a bit over the new few posts. Today we’re going to cover initializing the database.

One of the exciting features of EF 4 is the ability for the framework to generate the database based on the code model – this is what “Code First” is all about. As I showed in my last post, all you need to do is define a few classes, add them as DbSets<T> to the DbContext and the appropriate datastore will be created for you.

I’m going to add a new property to my Master class now – the level of the master.

public class Master
{
  [Key]
  public int MasterID{get; set;}

  public string Name{get;set;}

  public string Level { get; set; }

  public virtual ICollection<student> Students{get;set;}
}

 

Now if I simply run my program, I get an exception…

image

I think framework exceptions have come a long way. If you read the exception, it actually tells you what to do to stop it happening again. In this case, it’s saying if I want to use the context with the database we used previously, I can’t. What I can do however is either manually delete the database and re-run the program, which will re-create the database with my new column. But that might get tiresome in a rapid development cycle where the domain is changing all the time.

So instead we can define a database initialization strategy, which inherits from IDatabaseInitializer<TContext>. There are three pre-defined strategies to choose (derive) from:

  • CreateDatabaseIfNotExists<TContext> (this is default)
  • DropCreateDatabaseAlways<TContext>
  • DropCreateDatabaseIfModelChanges<TContext>

When your database dropped and recreated, your data is lost.

Okay, so lets use the second of the three options so I always have a clean database.

  public class DojoContextInitializer : 
      System.Data.Entity.Database.DropCreateDatabaseIfModelChanges<dojocontext>
  {

  }

 

To use the initializer, call the static method on the DbDatabase:

DbDatabase.SetInitializer(new DojoContextInitializer());

If you run the program now and inspect the database, you’ll see the new column has been added to the Masters table.

Deleting your database is annoying if you then have to go putting data back in, so the initializer gives a virtual method to override that can be used to Seed your database. Here I am using the Seed method to add an initial set of data.

protected override void Seed(DojoContext context){
  context.Masters.Add(new Master{
		Name = "paul johnston",
                Students = new List<student> { 
			new Student { Name = "Jenny Townsend" }, 
			new Student { Name = "Jack Philby" } }
            });
  //will not create the index in SQL CE, but will in SQLServer
  (context as IObjectContextAdapter)
	.ObjectContext
		.ExecuteStoreCommand(
		"CREATE INDEX IX_MASTERS_NAME ON MASTERS (NAME)");
}

I real scenarios, you might want to add indexes and such to the tables. To do this you can execute DDL against the database using the ObjectContext. To get the ObjectContext from the DbContext, you need to cast it as IObjectContextAdapter. To do this you will need to add a reference to System.Data.Entity.

This post has covered the basics of database initialization with the Entity Framework CTP 5 “Code First” framework. In my next post I will be covering basic configuration using the Fluent API.

Advertisements
This entry was posted in Entity Framework and tagged , . Bookmark the permalink.

One Response to Inititializing the DbContext

  1. Sylvain says:

    Hey dude,

    Thanks for the post. I’m new to EF and it helped explain a few things that were confusing the hell out of me.

    Cheers.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s