Learning Entity Framework (Day 2): Code First Approach and Code First Migrations in Entity Framework


Introduction

The intent of this article is to explain the code first approach and code first migrations that Microsoft’s Entity Framework provides. In my last article, I explained the theory behind the Entity Framework and the other two approaches, i.e., database first and model first approach. We’ll go step by step to explore the code first approach via which we can access the database and data using Entity Framework in our application. I’ll use Entity Framework version 6.2 and .NET Framework 4.6. and Visual Studio 2017 for the tutorial. For the database, we would be using SQL Server. You can make use of local database if do not have SQL Server installed.

Series Info

We’ll follow a five-article series to learn the topic of Entity Framework in detail. All the articles will be in tutorial form except the last where I’ll cover the theory, history, and use of EF. Following are the topics of the series.

Code First Approach And Migrations In Microsoft .NET Entity Framework

Code First Approach

The code first approach is the recommended approach with EF especially when you are starting the development of an application from scratch. You can define the POCO classes in advance and their relationships and envision how your database structure and data model may look like by just defining the structure in the code. Entity Framework, at last, will take all the responsibility to generate a database for you for your POCO classes and data model and will take care of transactions, history, and migrations.

With all the three approaches you have full control over updating the database and code as per need at any point in time.

Code First Approach And Migrations In Microsoft .NET Entity Framework

Using code first approach, a developer’s focus is only on code and not on database or data model. The developer can define classes and their mapping in the code itself and since now, the Entity Framework supports inheritance which makes it easier to define relationships. Entity Framework takes care of creating or re-creating database for you and not only this while creating a database, but you can also provide seed data i.e. master data that you want your tables should have when the database is created. Using code first, you may not have a .edmx file with relationships and schema as it does not depend upon Entity Framework designer and its tools and would have more control over the database since you are the one who created classes and relationships and managing it. There is a new concept of code first migrations that came up which makes code first approach easier to use and follow, but in this article, I’ll not use migrations but old method of creating DB context and DB set classes so that you understand what is under the hood. Code first approach could also be used to generate code from an existing database, so basically it offers two methods in which it could be used.

Code First Approach in Action

  1. Create a new console application named EF_CF. This will give you Program.cs and a Main() method inside that.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. We’ll create our model classes now, i.e., POCO (Plain Old CLR Object) classes. Let’s say we have to create an application where there would be database operations for an employee and an employee would be allocated to some department. So, A department can have multiple employees and an employee will have only one department. So, we’ll create the first two entities, Employee, and Add a new class to the project named Employee and add two simple properties to it i.e. EmployeeId and EmployeeName.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Similarly, add a new class named Department and add properties DepartmentId, DepartmentName, and DepartmentDescription as shown below.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Since an employee belongs to one department, each employee would have a related department to it, so add a new property named DepartmentId to the Employee class.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Now, it is time to add EntityFramework to our project. Open the Package Manager console, select the default project as your current console application, and install the Entity Framework. We already did this a couple of time before, so it won’t be a problem now on how to install it.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Since we are doing everything from scratch, we need our DBContext class as well. In model first and database first, we got the DBContext class generated. But, in this case, we would need to create it manually. Add a new class named CodeFirstContext to the project which inherits from DbContext class of namespace System.Data.Entity as shown in the following image. Now add two DbSet properties named Employees and Departments as shown in the following.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    The final code may look like this.

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Data.Entity;
    4. using System.Linq;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace EF_CF
    8. {
    9.     public class CodeFirstContext: DbContext
    10.     {
    11.         public DbSet<Employee> Employees { get; set; }
    12.         public DbSet<Department> Departments { get; set; }
    13.     }
    14. }
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    Both DbContext and DbSet are our superheroes in creating and dealing with database operations, and make us far abstracted, providing ease of use to us.

    When we are working with DbContext, we are in real working with entity sets. DbSet represents a typed entity set that is used to perform create, read, update, and delete operations. We are not creating DbSet objects and using them independently. DbSet can be only used with DbContext.

  1. Let’s try to make our implementation a more abstract and instead of accessing dbContext directly from the controller, let’s abstract it in a class named DataAccessHelper. This class will act as a helper class for all our database operations. So, add a new class named DataAccessHelper to the project.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Create a read-only instance of the DB context class and add few methods like FetchEmployees() to get employees details, FetchDepartments() to fetch department details. One method each to add employee and add a department. You can add more methods to your will like the update and delete operations. For now, we’ll stick to these four methods.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    The code may look like as shown below,

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace EF_CF
    7. {
    8.     public class DataAccessHelper
    9.     {
    10.         readonly CodeFirstContext _dbContext = new CodeFirstContext();
    11.         public List<Employee> FetchEmployees()
    12.         {
    13.             return _dbContext.Employees.ToList();
    14.         }
    15.         public List<Department> FetchDepartments()
    16.         {
    17.             return _dbContext.Departments.ToList();
    18.         }
    19.         public int AddEmployee(Employee employee)
    20.         {
    21.             _dbContext.Employees.Add(employee);
    22.             _dbContext.SaveChanges();
    23.             return employee.EmployeeId;
    24.         }
    25.         public int AddDepartment(Department department)
    26.         {
    27.             _dbContext.Departments.Add(department);
    28.             _dbContext.SaveChanges();
    29.             return department.DepartmentId;
    30.         }
    31.     }
    32. }
  1. Let’s add the concept of navigation property now. Navigation properties are those properties of the class through which one can access related entities via the Entity Framework while fetching data. So while fetching Employee data we may need to fetch the details of its related Departments and while fetching Department data we may need to fetch the details of associated employees with that. Navigation properties are added as virtual properties in the entity. So, in Employee class, add a property for Departments returning a single Department entity and make it virtual. Similarly, in Department class, add a property named Employees returning the collection of Employee entity and make that virtual too.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    Following is the code for the Employee and the Department model,

    Employee

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace EF_CF
    7. {
    8.     public class Employee
    9.     {
    10.         public int EmployeeId { get; set; }
    11.         public string EmployeeName { get; set; }
    12.         public int DepartmentId { get; set; }
    13.         public virtual Department Departments { get; set; }
    14.     }
    15. }

    Department

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Security.Policy;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace EF_CF
    8. {
    9.     public class Department
    10.     {
    11.         public int DepartmentId { get; set; }
    12.         public string DepartmentName { get; set; }
    13.         public string DepartmentDescription { get; set; }
    14.         public virtual ICollection<Employee> Employees { get; set; }
    15.     }
    16.  
  1. Let’s write some code to perform database operations with our code. So, in the Main() method of Program.cs class add the following sample test code,
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace EF_CF
    7. {
    8.     class Program
    9.     {
    10.         static void Main(string[] args)
    11.         {
    12.             Department department = new Department
    13.             {
    14.                 DepartmentName = “Technology”,
    15.                 Employees = new List<Employee>
    16.                 {
    17.                     new Employee() {EmployeeName = “Jack”},
    18.                     new Employee() {EmployeeName = “Kim”},
    19.                     new Employee() {EmployeeName = “Shen”}
    20.                 }
    21.             };
    22.             DataAccessHelper dbHelper = new DataAccessHelper();
    23.             dbHelper.AddDepartment(department);
    24.             var addedDepartment = dbHelper.FetchDepartments().FirstOrDefault();
    25.             if (addedDepartment != null)
    26.             {
    27.                 Console.WriteLine(“Department Name is: “ + addedDepartment.DepartmentName + Environment.NewLine);
    28.                 Console.WriteLine(“Department Employees are: “ + Environment.NewLine);
    29.                 foreach (var addedDepartmentEmployee in addedDepartment.Employees)
    30.                 {
    31.                     Console.WriteLine(addedDepartmentEmployee.EmployeeName + Environment.NewLine);
    32.                 }
    33.                 Console.ReadLine();
    34.             }
    35.         }
    36.     }
    37. }

    In the above code of Main() method, we are trying to create an object of Department class and add a list of Employees to the Employees property of that class. Create an instance of the dbHelper class and invoke the method AddDepartment, passing the department entity object to that method to add the new department.

    Just after adding the department, we are fetching the newly added department and just to make sure that the department and its related employees got added successfully to the database. So, we’ll fetch the departments and on the console, print the department name and its related employees. But how will all this be done, we do not have a database yet ☹

  1. Not to worry, let’s see how we can make sure that we get the DB created from our code. First like we saw earlier, our context class name should be the same as our connection string name or vice versa. So, add a connection string having the same name as DB context class in the App.config file as shown below.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    Job done! Entity Framework will take care of the rest of the pending work of creating a database. We just run the application and now, DB context class is first used to perform a DB operation, we get our database created.

  1. Put a breakpoint on the main method and run the application.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. As soon as the line where we write the code to AddDepartment gets executed, our database is created.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Go to the database server and see we got the database created with the same name that we supplied in the connection string. We have Departments and Employees table and a table named __MigrationHistory to track the history of code first migrations performed on this database.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    We see that we also got one Department added in the database having the name ”Technology” that we used in the code.

    Code First Approach And Migrations In Microsoft .NET Entity Framework

    And, got our employee’s table filled with three rows having three employees with department id 1 i.e. the id of the newly added department. And so our code first approach worked as well.

    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. You can proceed to press F5, to run the application and when console window appears we see the details of the department and added employees in that window, so our fetch operations also work fine.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

Though we covered all the approaches of the Entity Framework. I would like to show the code first migrations as well now to make you understand how to code first migrations work with Entity Framework. Before that, we need to know what is the requirement of migrations and what is the benefit of having migrations while working with the code first approach.

Code First Options

The Entity Framework code first approach provides us with three approaches while creating the database.

CreateDatabaseIfNotExists

It is the default option provided as an initializer class for code first approach. This option helps us create a database only if there is no existing database and so any accidental dropping of the database could be avoided via this option.

DropCreateDatabaseWhenModelChanges

This initializer class keeps an eye on the underlying model and if the model changes, it drops the existing database and re-creates a new one. It is useful when the application is not live and the development and testing phase is going on.

DropCreateDatabaseAlways

This option as the name says always drops and creates a database whenever you run the application. It is most useful in testing when you are testing with the new set of data every time.

Code First Migrations

Imagine a scenario where you want to add a new model/entity and you do not want the existing database to get deleted or changed when you update the database with the newly added model class. Code first migrations here help you to update the existing database with your newly added model classes and your existing database remains intact with the existing data. So, the data and schema won’t be created again.

Code First Migrations in Action

Let’s see how we can work with code first migrations step by step like we did for other approaches.

  1. Add a new console application named EF_CF_Migrations.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Add the Department model with properties DepartmentId, DepartmentName and DepartmentDescription. Add a virtual property as a navigation property called Employees because a department can have multiple employees.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Similarly, add a model class named Employee and add three properties as EmployeeId, EmployeeName, DepartmentId, and Departments as a navigation property as an employee may be associated with any department.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Install Entity Framework from the package manager console as shown in the following,
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Add a context class deriving from DbContext class and add Employee and Department class as a DbSet property in the class.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Now, execute command named “Enable-Migrations” but before that select the default project as your newly added project. The command has to be executed using the package manager console.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Once the command is executed, you’ll get a folder in your application named “Migrations” and by default, a class named Configuration would be added that holds your initial configurations and all other configurations you want to have with code first approach. You can configure the settings in the constructor of this class. This class derives from DbMigrationsConfigurations which has a virtual method Seed in the base class. We can override the method in our derived class to add some seed data to our database when it gets created.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. The Seed method takes the context as a parameter. Context is the instance of our CodeFirstContext class. Now add sample data to the context for e.g. as shown below, I am adding one department named Technology with three sample employees and one additional employee separately to the context. The class will look similar to the code below.
    1. using System.Collections.Generic;
    2. namespace EF_CF_Migrations.Migrations
    3. {
    4.     using System;
    5.     using System.Data.Entity;
    6.     using System.Data.Entity.Migrations;
    7.     using System.Linq;
    8.     internal sealed class Configuration : DbMigrationsConfiguration<EF_CF_Migrations.CodeFirstContext>
    9.     {
    10.         public Configuration()
    11.         {
    12.             AutomaticMigrationsEnabled = false;
    13.         }
    14.         protected override void Seed(EF_CF_Migrations.CodeFirstContext context)
    15.         {
    16.             Department department = new Department
    17.             {
    18.                 DepartmentName = “Technology”,
    19.                 Employees = new List<Employee>
    20.                 {
    21.                     new Employee() {EmployeeName = “Jack”},
    22.                     new Employee() {EmployeeName = “Kim”},
    23.                     new Employee() {EmployeeName = “Shen”}
    24.                 }
    25.             };
    26.             Employee employee = new Employee
    27.             {
    28.                 EmployeeName = “Akhil Mittal”,
    29.                 DepartmentId = 1
    30.             };
    31.             context.Departments.AddOrUpdate(department);
    32.             context.Employees.AddOrUpdate(employee);
    33.         }
    34.     }
    35. }
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Now execute one more command that says “Add-Migration Initial” on package manager console. This command, when executed, creates one more file under the Migrations folder.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    The name of the file comprises of the date-time stamp and is appended with the keyword “_Initial”. This class derives from DbMigration class that has a virtual Up() method. The command overrides this method in the generated class and adds statements to create the database tables when our code will execute. Similarly, the Down() method is the opposite of the Up() method.

    Code First Approach And Migrations In Microsoft .NET Entity Framework

    Following is the code that got generated for us when we added the initial migration. The Up method holds the database statements and takes care of foreign key constraints as well while creating tables in the database.

    1. namespace EF_CF_Migrations.Migrations
    2. {
    3.     using System;
    4.     using System.Data.Entity.Migrations;
    5.     public partial class Initial : DbMigration
    6.     {
    7.         public override void Up()
    8.         {
    9.             CreateTable(
    10.                 “dbo.Departments”,
    11.                 c => new
    12.                     {
    13.                         DepartmentId = c.Int(nullable: false, identity: true),
    14.                         DepartmentName = c.String(),
    15.                         DepartmentDescription = c.String(),
    16.                     })
    17.                 .PrimaryKey(t => t.DepartmentId);
    18.             CreateTable(
    19.                 “dbo.Employees”,
    20.                 c => new
    21.                     {
    22.                         EmployeeId = c.Int(nullable: false, identity: true),
    23.                         EmployeeName = c.String(),
    24.                         DepartmentId = c.Int(nullable: false),
    25.                     })
    26.                 .PrimaryKey(t => t.EmployeeId)
    27.                 .ForeignKey(“dbo.Departments”, t => t.DepartmentId, cascadeDelete: true)
    28.                 .Index(t => t.DepartmentId);
    29.         }
    30.         public override void Down()
    31.         {
    32.             DropForeignKey(“dbo.Employees”“DepartmentId”“dbo.Departments”);
    33.             DropIndex(“dbo.Employees”new[] { “DepartmentId” });
    34.             DropTable(“dbo.Employees”);
    35.             DropTable(“dbo.Departments”);
    36.         }
    37.     }
    38. }
  1. There, still is a gap that needs to be bridged before we proceed. We’ll need to have a connection string with the same name as of our context class in our App.config. So open the app.config file of the project and add the connection string as needed with the server and database name details.
    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. The last step of migrations is to execute a command that says “Update-Database”.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    This command, when executed on package manager console, applies all the migrations we have under the Migrations folder and runs the seed method of Configuration class.

    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Now, go to the database to check if we got our tables created or not with the sample data that we provided in the seed method. In the image below we see the Departments table having the sample department that we added in seed method to context as Department model.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    In the Employees table, we have all the employees associated with that department and one additional employee as well that we added via the seed method.

    Code First Approach And Migrations In Microsoft .NET Entity Framework
  1. Let’s add some code to our program.cs class to check if the database operations are working fine or not. So, create an instance of CodeFirstContext and add one more sample department with sample employees and save the changes.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

    Following is the code.

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace EF_CF_Migrations
    7. {
    8.     class Program
    9.     {
    10.         static void Main(string[] args)
    11.         {
    12.             CodeFirstContext context =new CodeFirstContext();
    13.             Department department = new Department
    14.             {
    15.                 DepartmentName = “Management”,
    16.                 Employees = new List<Employee>
    17.                 {
    18.                     new Employee() {EmployeeName = “Hui”},
    19.                     new Employee() {EmployeeName = “Dui”},
    20.                     new Employee() {EmployeeName = “Lui”}
    21.                 }
    22.             };
    23.             context.Departments.Add(department);
    24.             context.SaveChanges();
    25.         }
    26.     }
    27. }
  1. Run the code by pressing F5 and then go to the database to check if the records for department and Employees associated with it got inserted or not. We see in the following image while selecting top records from Departments table, we get one additional department that we just created.
    Code First Approach And Migrations In Microsoft .NET Entity Framework

Similarly, we get added Employees for the newly added department as shown in the following image.

Code First Approach And Migrations In Microsoft .NET Entity Framework

MigrationHistory Table

This is the most important part of code first migrations. We see that along with our entity tables we got an additional table named __MigrationHistory. This table takes responsibility to hold all the migrations history that we add from the code. For e.g., check the row that it got initially. The MigrationId column of the first row contains the value that is the same as the name of the file that got created when we added migrations in our code. It contains the hash and every time we add or modify something in the model and run update migrations command, it checks the history in the database and compares with the existing files of migrations that we have in our Migrations folder. If the file is new, it executes that file only and not the old ones. This helps us to track database changes in the more organized way. One can also revert back to a particular migration from code by supplying the migration id of that migration. Migration id is nothing but the name of the migration file and the same that got stored in the __MigrationHistory table as the column value. The following two images show that the column value in the MigrationHistory table and the file name in the code for migration is similar.

Code First Approach And Migrations In Microsoft .NET Entity Framework

Code First Approach And Migrations In Microsoft .NET Entity Framework

In case, you add a new migration, a new file would be created with a unique name having date-time stamp and when you run update migration, a new row will be inserted into the __MigrationHistory table for the same having same column value as the name of the newly added file.

Code First Approach And Migrations In Microsoft .NET Entity Framework

Conclusion

In this article, we closely looked at how we can leverage the Entity Framework’s code first approach and as per need use those. I took the basic console application to explain the concept, but these could be used in any enterprise level application that uses WebAPI’s, Asp.net projects or MVC projects as well. We closely looked into code first migrations and importance of migration table as well.

Advertisements

Author: Akhil Mittal

Akhil Mittal is a Microsoft MVP(Most Valuable Professional), C# Corner MVP, Codeproject MVP, a blogger, author and likes to write/read technical articles. Akhil has an experience of around 11 years in developing, designing, architecting enterprises level applications primarily in Microsoft Technologies. Akhil enjoys working on technologies like MVC, Web API, Entity Framework, Angular, C# and BlockChain. Akhil is an MCP( Microsoft Certified Professional) in Web Applications (MCTS-70-528, MCTS-70-515) and .Net Framework 2.0 (MCTS-70-536). Visit Akhil Mittal’s personal blog CodeTeddy (https://codeteddy.com) for some good and informative articles.