CodeDigest.Com Logo
Featured:

Learn Entity Framework Code First in 10 Minutes

Entity Framework is Microsoft’s ORM (Object-Relational Mapping) framework for data access. Entity Framework initially supported Model First or Database First approach for modeling domain objects in a XML based edmx files. Entity Framework Code First is another approach released with Entity Framework 4.1 version.

 

As the name suggests, in Code First approach we can define domain class first and the Code First framework will create the database on the fly based on the domain class definition. In other words, designing the domain model classes first is called Domain Driven Design and allows developers to concentrate and think through in terms of business domain objects rather than creating domain model classes to match the database design in Database First approach.

Defining Domain Classes

For easy understanding, let’s build a simple model with Employee and Department to under how Code First works.

 

public class Employee
{
    public int EmployeeId { get; set; }
    public int DepartmentId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

public class Department
{
    public int DepartmentId { get; set; }
    public string DepartmentName { get; set; }
}
 

 

These classes are nothing but a plain C# class which represents our domain in our project and it does not have anything related to Entity Framework or Code First paradigm. So, this makes easier for us to make an existing domain model classes to work with Code First or concentrate on designing business domain classes rather than thinking in terms of creating classes to supports a database structure. Next, let’s see how to let Code First know about these domain classes and manage it using Code First.

You need Entity Framework Nuget package to work with EF Code First. To include this, right click your project in Solution Explorer, click “Manage Nuget Packages..” and Search “EntityFramework”. Click Install and Click Accept when Nuget asks for License Agreements.

Managing Domain Objects with Code First

Entity Framework expose a class called DbContext for doing this. We just need to define a class that inherits System.Data.Entity.DbContext class and expose these domain objects as property member of this class through System.Data.Entity.DbSet<T> object. The DbSet object represents the collection of our entity that is persisted in the database by the DbContext object. It also gives the querying capabilities to the entity collection or the underlying table.

 

public class DBModel : DbContext
{
    public DbSet<Department> Departments { get; set; }
    public DbSet<Employee> Employees { get; set; }
}

 

 

Querying Using DBModel and Entity

Querying is similar to what we do with Entity Framework data access which uses LINQ construct. Let’s add some default rows into Employee and Department table now.

 

DBModel db = new DBModel();
if (db.Departments.Count() <= 0)
{
    Department department = new Department();
    department.DepartmentName = "IT";
    db.Departments.Add(department);
    department = new Department();
    department.DepartmentName = "CSE";
    db.Departments.Add(department);
}
if (db.Employees.Count() <= 0)
{
    Employee emp = new Employee();
    emp.FirstName = "Tom";
    emp.LastName = "Hanks";
    emp.Address1 = "1St Street";
    emp.Address2 = "Columbia Ave";
    emp.City = "Los Angeles";
    emp.State = "CA";
    emp.Country = "US";
    emp.PostalCode = "123456";
    emp.DepartmentId = 1;
    db.Employees.Add(emp);

    emp = new Employee();
    emp.FirstName = "Bruce";
    emp.LastName = "Willis";
    emp.Address1 = "2nd Street";
    emp.Address2 = "Farmers Ave";
    emp.City = "Seattle";
    emp.State = "WA";
    emp.Country = "US";
    emp.PostalCode = "756446";
    emp.DepartmentId = 2;
    db.Employees.Add(emp);

    emp = new Employee();
    emp.FirstName = "Johnny";
    emp.LastName = "Depp";
    emp.Address1 = "5Th Street";
    emp.Address2 = "Shuttle Ave";
    emp.City = "San Antonio";
    emp.State = "TX";
    emp.Country = "US";
    emp.PostalCode = "123456";
    emp.DepartmentId = 2;
    db.Employees.Add(emp);
}
db.SaveChanges();
 

 

Executing above code (you can create a console application and use the above code from Main() method) will create and insert the Employee and Department table data. One thing to note here, we never configured or mentioned where the database needs to be created. Code First by default will create it in local SQL Server Express database as seen in below figure. It uses the DbContext class fully qualified name as database name. My DBModel class is residing under GridDemo.Models.DL namespace.

Specifying Explicit Connection String

Let’s override the default behavior and specify the connection string ourselves to point to a database in another location. To use a local SqlExpress database under App_Data in our web project, it is just enough if we specify the connection string with key that matches our DbContext class name.

 

<connectionStrings>

<add name="DBModel" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=True;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient" />

</connectionStrings>

 

On execution, this will create a new database under App_Data folder in our project and it can be viewed through server explorer in visual studio.

Alternatively, you can also specify the connection string explicitly by calling DbContext constructor similar to below.

public class DBModel : DbContext
{
    public DBModel()
        : base("name=DefaultConnection")
    {
    }
    public DbSet<Department> Departments { get; set; }
    public DbSet<Employee> Employees { get; set; }
}

 

The above configuration requires a connection string in Web.Config with key DefaultConnection.

All the above works by default without any configuration by following Code First conventions. Entity Framework Code First relies heavily on conventions to manage the domain classes and database creation.

For example, a primary key field is identified and created when Code First finds a property with TypeName followed by “Id” string. This is how EmployeeId and DepartmentId are created as primary key. Code First also allows us to customize this conventions through number of configuration options.

There are primarily 2 ways to use the configurations to dictate terms to Code First. They are,

  1. By using Data Annotations

  2. By using Fluent API

Using Data Annotations

To make FirstName and LastName as not null columns (or mandatory in domain) we just need to decorate those property using [Required] attribute from System.ComponentModel.DataAnnotations namespace.

 

public class Employee
{
    public int EmployeeId { get; set; }
    public int DepartmentId { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

 

This will make the FirstName and LastName column as not null in database. Similarly, the DataAnnotations namespace has many properties to configure Code First database model properties.

Fluent API

Instead of using Data Annotations and mixing Entity Framework constructs in domain model we can specify the configurations using Fluent API inside DbContext OnModelCreating event and keep the domain model clean. The above not null configuration can done by,

 

public class DBModel : DbContext
{
    public DbSet<Department> Departments { get; set; }
    public DbSet<Employee> Employees { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>().Property(p => p.FirstName).IsRequired();
        modelBuilder.Entity<Employee>().Property(p => p.LastName).IsRequired();
    }
}

 

Note - There are few configurations that cannot be done by Data Annotations and can be done only through Fluent API.

Database Initializers and Code First Migrations

Though the above approaches creates database automatically, we can also set Database Initializers to manage database creation process.

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DBModel>());

 

Calling the above statement before using the DbContext(or DBModel) will re-create database fully if there is a change detected in the model object after it has last created.

There are other initializers like,

  • CreateDatabaseIfNotExists – To create DB if not exists and a default option.

  • DropCreateDatabaseAlways – To recreate DB always.

These Database Initializers are very basic and cannot be used in real time as our production applications are incrementally built and so the database too. Entity Framework 4.3 has introduced a strategic tool called Code First Migrations for this advanced tasks. The additional table you see dbo.__MigrationHistory in the database created by Code First is used by this framework for detecting changes and managing the migrations.