Using Code first approach with Entity Frameworks Migration tool

In one of my previous post I have done a simple overview of how to use Entity Frameworks code first approach for MVC4 project. I did a simple overview on how to use the Scaffolding to generate Views, Controllers and update database from model classes.

 

On this post I will make things a little simpler, I will show you how easy it is to use the Entity Frameworks Migrations to use the code first approach. Hopefully you will get some sort of benefits from it.

 

For this project, I created a simple WCF class library project ( you can do just class library too).

 

First step, go to Tool –> Library Package Manager –> Manage NuGet packages for Solution

 

This will open up the Nuget Package window, Find Entity Framework and install it.

image

 

Next I went to the App.Config file and added the following lines under the <congifuration>

 

<configSections>

    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

  </configSections>

  <connectionStrings>

    <add name="HowToUseMigration" connectionString="Server=[your server];Database=[Database Name];Uid=[user];Pwd=[password];" providerName="System.Data.SqlClient" />

  </connectionStrings>

 

Now on your project you have your connectionstring that is pointing to a Database.

You need to create the Database shell on your SQL server.

 

Next thing you need is a way to tell the project that you want to use the Migration tool.

 

go to Tool –> Library Package Manager –> Package Manager Console

This will open the a windon on the bottom (depends on your setting), and You will see PM>

Make sure you are pointing at the proper project, if you have more than one project

 

image

 

You need to specify a class that is derived from DbContext, Migration will use this to setup the database activity.

I manually created a Folder called Models, add a class as following

using System;

using System.Collections.Generic;

using System.Data.Entity;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public class AuthenticationContext : DbContext

    {

        public AuthenticationContext()

            : base("name=[Connectionstring name goes here")

        {

            

        }

 

    } 

}

 

Now we are ready to type again

PM> Enable-Migrations

No context type was found in the assembly ‘TestService’.

 

This is ok, it means that we haven’t defined any class that the migration tool can use to create the database tables. If you look in your project you should have a Migration folder with

Configuration.cs file in it. This is where we can change settings add Seed data.

 

 

We will basically create a User, Role and UserRole Table. Simple one to many relationship with UserRole reference table.

image

 

 

Our User Class will look like this, if you look closely you will see that I am using DataAnnotation to define data properties for the item. You can control a lot of things this way. I have an abstract base class that has some basic things that I want on each table.

 

using System;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public class User :BaseClass

    {

        const string EmailPattern = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

        [MaxLength(50),Required]

        public string FirstName { get; set; }

 

        [MaxLength(50)]

        public string MiddleName { get; set; }

 

        [MaxLength(50), Required]

        public string LastName { get; set; }

 

        [MaxLength(16), Required]

        public string UserName { get; set; }

 

        [MaxLength(16), Required]

        public string Password { get; set; }

 

        [MaxLength(50), Required]

        [RegularExpression(EmailPattern)]

        public string Email { get; set; }

 

        [Required]

        public Guid UserGuid { get; set; }

    }

}

 

Here is the Role table looks like, very simple.

 

using System;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public class Role : BaseClass

    {

        [Required]

        public string RoleName { get; set; }

        public string Description { get; set; }

    }

}

 

 

Before I get too deep here is the base class. It supply the Id field, Created By, Create Date, Updated By and Updated Date for all the classes

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public abstract class BaseClass

    {

        public int Id { get; set; }

 

        [MaxLength(50),Required]

        public string CreatedBy { get; set; }

 

        [Required]

        public DateTime CreateDate { get; set; }

 

        [MaxLength(50)]

        public string UpdatedBy { get; set; }   

        

        

        public DateTime? Updated { get; set; }

    }

}

 

Fun part is to set the one to many relations for the Migration.

using System;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public class UserRole : BaseClass

    {

        public bool IsActive { get; set; }

 

        //1-* relation with User table

        public int UserId { get; set; }

        public virtual User User { get; set; }

 

        //1-* relation with Roles

        public int RoleId { get; set; }

        public virtual Role Role { get; set; } 

 

    }

}

 

 

Now we need to tell the Migrations which classed should create table in the DB

We have to go back to the AuthenticationContext that was derived from DbContext

using System;

using System.Collections.Generic;

using System.Data.Entity;

using System.Linq;

using System.Text;

 

namespace TestService.Models

{

    public class AuthenticationContext : DbContext

    {

        public AuthenticationContext()

            : base("name=[ConnectionString name")

        {

            

        }

        public DbSet<User> Users { get; set; }

        public DbSet<Role> Roles { get; set; }

        public DbSet<UserRole> UserRoles { get; set; } 

 

    } 

}

 

That is all the setup in the code we need. Now if you run the following command

 

PM> Update-Database –Verbose –force

 

This will create your Database tables. Now if you want to get the the database created everytime and add seed data go to the Migrations folder and click on the Configuration.cs  and change the seed

and change AutomaticMigrationEnabled to True on constructor.

 

 

using TestService.Models;

 

namespace TestService.Migrations

{

    using System;

    using System.Data.Entity;

    using System.Data.Entity.Migrations;

    using System.Linq;

 

    internal sealed class Configuration : DbMigrationsConfiguration<TestService.Models.AuthenticationContext>

    {

        public Configuration()

        {

            AutomaticMigrationsEnabled = true;

        }

 

        protected override void Seed(Models.AuthenticationContext context)

        {

            //This add one default role for seed data

            var defaultRole = new Role

                                  {

                                      RoleName = "Default",

                                      Description = "Default Role",

                                      CreateDate = DateTime.Now,

                                      CreatedBy = "System"

                                  };

 

            context.Roles.Add(defaultRole);

 

        }

    }

}

 
 
Now you are all set.
 
run the command again
 
PM> Update-Database –Verbose –force
 
 
Check your Database and you will like what you see.
 
Hope this helps you.

Leave a Reply

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