Click here to Skip to main content
15,122,559 members
Articles / Web Development / HTML
Article
Posted 20 Mar 2016

Tagged as

Stats

41.8K views
327 downloads
20 bookmarked

Code First Approach in MVC using Migration

Rate me:
Please Sign up or sign in to vote.
4.97/5 (27 votes)
20 Mar 2016CPOL5 min read
How to use Code First Approach in MVC using Migration
This article will show you how to implement Code First approach and CRUD Operations using Code First. You will learn how to use Migration in case of Code First. This tutorial will be helpful for beginners who want to learn code-first approach from scratch.

Introduction

There are three different approaches to implement Entity Framework in applications:

  1. Database First
  2. Model First
  3. Code First

Which approach we should use is not the intent of this article but here are some points on which we can decide which approach we should use.

Database First: If we have existing database, then we should choose Database first approach. In this approach, we can generate a model based on our database. In this approach, we create an .edmx file where all the information gets saved.

Model First: If we don't have any existing database, then we can create a conceptual model through this approach and later, we can create a SQL script to create database.

Code First: If we don't have any existing database, then we can go for Code first approach. In this approach, Entity Framework will not create any .edmx or hidden code. Using this approach, we design our model classes and with the help of these model classes, database gets created automatically.

In this article, we will see how we implement Code First approach and CRUD Operations using Code First. We will see how we use Migration in case of Code First. This tutorial is helpful for beginners who want to learn code-first approach from scratch.

Code First Approach

In Code First Approach, we don't create .edmx file. We create our Model class and with the help of those model classes, database gets created automatically.

Image 1

Starting the Code

1. Open Visual Studio and Go to File --> New-->Project and Create a New MVC project (I am using MVC4 and Visual Studio 2012) as below and give a name to it. (In my case, name is CodeFirstApproach.)

Image 2

2. Add a Model in Model Folder named Student and apply some attributes which we have inside System.ComponentModel.DataAnnotations namespace.

C++
public class Student
   {
       [Key]
       public int ID { get; set; }
       [StringLength(50)]
       public string Name { get; set; }
       [StringLength(50)]
       public string Email { get; set; }
       [StringLength(50)]
       [DataType(DataType.Password)]
       public string Password { get; set; }
   }

Main Player of Code First (Context Class)

Context class is the main player of code first. Create a context class in Model Folder and give a name to it (In my case, name is MyDataContext.cs) and inherit this from DBContext class and add a constructor in MyDataContext class and call base class constructor and pass the connection string to the base class constructor as below.

Note: For DbContext class, use System.Data.Entity Namespace.

C++
public class MyDataContext : DbContext
   {
     public MyDataContext():base("Data Source=.;Initial Catalog=CodeFirst;
                                  trusted_connection=true")
      {

      }

     public DbSet<Student> Students { get; set; }
   }

Note: We can give the connection string name from the web config file also rather than complete connection string name. In that case, we will pass only connection string name instead of complete connection string.

Add a Controller and Action Method

Add a controller named StudentController and add an action method named AddStudent.

C++
public class StudentController : Controller
    {
        [HttpGet]
        public ActionResult AddStudent()
        {
            return View();
        }
    }

Add a view (Right click on the View and click Add View). Select Create Strongly-TypedView and select Student class which we created in our Model Folder as a Model class. Select Create in Scaffold Templates.

Image 3

Run the application and Type Student/AddStudent in the URL as ControllerName/ActionName.

Image 4

Create another action method in StudentController which will handle the post request. In this action method, we will create the object of my context class and add student entity in Students DbSet.

C++
public class StudentController : Controller
{
    [HttpGet]
    public ActionResult AddStudent()
    {
        return View();
    }
    [HttpPost]
    public ActionResult AddStudent(Student std)
    {
      using(MyDataContext objContext = new MyDataContext())
        {
            objContext.Students.Add(std);
            objContext.SaveChanges();
        }
        return View();
    }
}

Fill the Student Form and click on create button. We will see a new database created (CodeFirst) and a table (Student) as below:

Image 5

In the above Table structure, we can see that Students table gets automatically created. Code First automatically creates ID as primary key and adds Identity on ID Column. Name, Email and Password column length is the same as we provided StringLength on Properties on Model Class.

After adding some more records through StudentForm, we have the below data in our student table:

Image 6

What if we need to add a extra column. Let's say address in our Model. So that complete model is:

C++
public class Student
    {
        [Key]
        public int ID { get; set; }
        [StringLength(50)]
        public string Name { get; set; }
        [StringLength(50)]
        public string Email { get; set; }
        [StringLength(50)]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        public string Address { get; set; }
    }

If we will run the app and add a student, we will get the below exception:

Image 7

Now we have three options:

  1. DropCreateDatabaseIfModelChanges: We can set this in our MyDataContext Constructor. But if we set this, then whenever our model will be changed, our database will drop and be recreated. So all the data in the database will be lost.
  2. DropCreateDatabaseAlways: We can set up this also in our MyDataContext Constructor. This will drop and create database always whenever we will perform any operation on our datacontext. So all the data in the database will be lost again.

We can set up these properties as below:

C++
public MyDataContext():base("Data Source=.;Initial Catalog=CodeFirst;
                             trusted_connection=true")
   {
     Database.SetInitializer<MyDataContext>
              (new DropCreateDatabaseIfModelChanges<MyDataContext>());
   }

or:

C++
public MyDataContext():base("Data Source=.;Initial Catalog=CodeFirst;
                             trusted_connection=true")
   {
       Database.SetInitializer<MyDataContext>
                (new DropCreateDatabaseAlways<MyDataContext>());
   }

In both the above options, we are losing data. So what if we don't want to lose our data and want to add an extra column in our table. As we have some Additional Information in the above exception, we can take the help of Migrations approach in such scenarios.

Code First Migrations Approach

To use the Code First Migrations, first we need to enable the Migrations in our project.

To enable Migrations, Go to Tools-->NuGet Package Manager and then Open Package Manager Console.

Run the below commands one by one:

  1. PM> UnInstall-Package EntityFramework
  2. PM> Install-Package EntityFramework
  3. PM> Enable-Migrations -ContextTypeName CodeFirstApproach.Models.MyDataContext

    Once we will run the above commands, a migrations folder will get added in our solution which will contain a configuration class file and another file with date Time stamp. This file contains the initial state of table.

    Now run the below command with a MigrationName (AddAddressProperty in my case).

  4. PM> Add-Migration AddAddressProperty

    The above command will create another file in Migrations Folder and which contains the changes you made in your model after the last Migration.

    Now update your database.

  5. PM> Update-Database

    Now check the Students table, a new column named address will be there.

Now every time we will add a column in our model, we need to perform the above steps. Ohh No... Automatic Migration is here for our help.

Automatic Migration

In the constructor of this configuration file, set AutomaticMigrationsEnabled = true and in your MyDataContext Constructor, set the below initializer

C++
public MyDataContext():base("Data Source=.;Initial Catalog=CodeFirst;trusted_connection=true")
      {
         Database.SetInitializer
         (new MigrateDatabaseToLatestVersion<MyDataContext, Configuration>());
      }

Now add another property in your model, let's say City and run the application again. Wow, this time it's added automatically in your table.

Insert Master Data (Using SQL Query) in Code First

Suppose we want to add a PhoneNo property in our model and want to give some default values. This can be easily done by using SQL query in code first approach.

Run the below command in PM Console window:

PM> Add-Migration AddPhoneNoProperty

This will create a file in Migration Folder. Open that file and add a SQL update statement as below:

C++
public partial class AddPhoneNoProperty : DbMigration
 {
     public override void Up()
     {
         AddColumn("dbo.Students", "PhoneNo", c => c.String());
         Sql("update students set PhoneNo=9711965544 where PhoneNo is null");
     }

     public override void Down()
     {
         DropColumn("dbo.Students", "PhoneNo");
     }
 }

This will add a PhoneNo column in student table with some default values as below:

Image 8

History

  • 20th March, 2016: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

VijayRana
Technical Lead
India India
Hi Myself Vijay having around 7 years of experience on Microsoft Technologies.

Comments and Discussions

 
GeneralExcellent Article Pin
Anant Aggarwal9-Mar-17 10:36
MemberAnant Aggarwal9-Mar-17 10:36 
QuestionPhone number? Pin
Akhil Mittal 10-Apr-16 20:39
professional Akhil Mittal 10-Apr-16 20:39 
AnswerRe: Phone number? Pin
VijayRana10-Apr-16 21:12
professionalVijayRana10-Apr-16 21:12 
GeneralRe: Phone number? Pin
Akhil Mittal 10-Apr-16 22:19
professional Akhil Mittal 10-Apr-16 22:19 
PraiseRe: Phone number? Pin
VijayRana10-Apr-16 22:27
professionalVijayRana10-Apr-16 22:27 
GeneralRe: Phone number? Pin
Akhil Mittal 10-Apr-16 22:30
professional Akhil Mittal 10-Apr-16 22:30 
GeneralMy vote of 5 Pin
saurabh.btech.it24-Mar-16 8:47
Membersaurabh.btech.it24-Mar-16 8:47 
GeneralMy vote of 5 Pin
Member 1240676721-Mar-16 23:38
MemberMember 1240676721-Mar-16 23:38 
GeneralMy vote of 5 Pin
Member 1240847921-Mar-16 21:25
MemberMember 1240847921-Mar-16 21:25 
PraiseMy Vote is 5... Pin
Munir Ahmd21-Mar-16 21:06
MemberMunir Ahmd21-Mar-16 21:06 
GeneralMy vote of 5 Pin
priyanka choudhary21-Mar-16 19:28
Memberpriyanka choudhary21-Mar-16 19:28 
GeneralMy vote of 1 Pin
priyanka choudhary21-Mar-16 19:23
Memberpriyanka choudhary21-Mar-16 19:23 
PraiseAwesome article Pin
SinghCharu21-Mar-16 9:47
MemberSinghCharu21-Mar-16 9:47 
Questionimage problems Pin
Nelek20-Mar-16 14:46
protectorNelek20-Mar-16 14:46 
GeneralRe: image problems Pin
VijayRana20-Mar-16 19:55
professionalVijayRana20-Mar-16 19:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.