Sex, drugs and sausage rolls

Tech and Life… as seen by Tallmaris (il Gran Maestro)

Entity Framework Primer: Initial Configuration and Migration

Hi All,

I have been experimenting a bit with Entity Framework, the new v5, and wanted to share some of the little nice things that can get you started quickly.

Setting up

First of all you may want to install Entity Framework through NuGet. Keep in mind that you don’t need to do that if you are using MVC4, since it comes already in:

PM> Install-Package EntityFramework

While you are in the console, you may want to enable migrations straight away using Enable-Migrations, but that will give you an error: No context type was found in the assembly 'MyProject'. This is because of course we did not even create a DbContext class so ideally we should not need Migrations or anything else.

Our sample App will be the typical ToDo app so to keep naming consistence we will create a ToDoDbContext in the Models folder:

public class ToDoDbContext : DbContext
{
}

Now you can do:

PM> Enable-Migrations

This will create a Migrations folder in the solution, with a Configuration.cs file in it. You can use this file to set some configuration options and to add data to the DB through a Seed() method that gets called after every migration.

Next, we may want to set up the right connection string for our application in the config file:

<add name="ToDoDbContext" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MyToDoDB;Integrated Security=SSPI" />

Your mileage may vary here, just select the appropriate connection string for your environment. You can keep the one named “DefaultConnection” if you want but I advise you to create a specific one; that is as simple as giving the connection string the name of your DbContext class (ToDoDbContext in our case).

First Model and Migration

Let’s create a typical Task model:

public class Task
{
    public int TaskId { get; set; }
    public string Description { get; set; }
    public bool Completed { get; set; }
}

Of course the table for this does not exist in the Db, but rather than creating it manually or relying on EF Automatic Migrations to create it for us, I suggest you actually manually create a migration for it. This will help to keep all the DB related activities in separated and easy to browse code files, which helps a lot when adding models later on.

Go back to the PM Console and type:

PM> Add-Migration -Name CreateTask

After a bit of thinking, VS will have created for you a file called 201301171502391_CreateTask.cs, where the first part is simply a timestamp, useful for giving a sort order to the migrations and apply only the latest ones to a DB. However, if you examine the file, you will notice that it is empty except for the two methods Up() and Down() and it is not actually adding any code for creating our table… Why is that? The answer is simply that the DbContext is empty, meaning that there are properties in it defined as DbSet that tell the migrator which classes to use to generate our tables.

Let’s go and add this property to our DbContext:

public class ToDoDbContext : DbContext
{
    public DbSet<Task> Tasks { get; set; }
}

and run Add-Migration -Name CreateTask again from the PM console.

If everything went ok, you should now see some code in the two methods in this class: Up() and Down(). The former will be invoked when applying the migration to the DB (so going up in version) the latter when downgrading the DB. The Up() method creates the dbo.Tasks table and adds the relevant columns:

CreateTable(
    "dbo.Tasks",
    c => new
        {
            TaskId = c.Int(nullable: false, identity: true),
            Description = c.String(),
            Completed = c.Boolean(nullable: false),
        })
    .PrimaryKey(t => t.TaskId);

Now we need to apply the migration to the DB: back to the NuGet console:

PM> Update-Database

This will run the migration and run any code you put in the Seed() method in the Configuration file, in case you want to add data immediately to your tables. If you connect to the DB with a Tool like Studio Management, you should see the Table created exactly as expected.

About the Seed() method, the best option is to follow the commented code that you find there to understand what to do. As an example, if in our case if you want to add 2 tasks from the start you would do something like:

protected override void Seed(ToDoDbContext context)
{
    context.Tasks.AddOrUpdate(
        t => t.Description,
        new Task { Description = "Task1", Completed = false },
        new Task { Description = "Task2", Completed = false }
    );
}

Since the Seed() is run after every migration, we need to use AddOrUpdate to avoid duplicates. The first parameter for AddOrUpdate is the field we want the seeding to use when determining if we are adding a new entity or updating an existing one: we use the Description property in our case.

Keep in mind that the Seed() method will be run even if there is nothing to migrate (i.e: the DB is already at the most up to date version)! So every time you run Update-Database on the NuGet console, the two tasks will go back to have Completed = false.

Next article we will have a look at a (real?) migration, needed to add fields to a model which means adding column to a DB table.

, , , ,

One thought on “Entity Framework Primer: Initial Configuration and Migration

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>