Code First Approach in Entity Framework

What is Code-First Approach?
Code first approach is something when we create business domain classes first without having any knowledge of database structure.

How EF Code First Approach Works

"Code First Approach" simply means when we write application object code first before we write database code, and database objects are generated from application code.

In this approach we first indentify all business domain entities and create them first, the Code-First approach was introduced with Entity Framework 4.1.

Code first design is a type of Domain Driven Design

Code First in Entity Framework C#

So, we create few custom classes first, here just to keep the example easy for you to understand we have created two simple classes called Customer and Order.

Step 1 : Create following two custom classes.

public class Customer            
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime RegDate { get; set; }
    public List<Order> Orders { get; set; }
}
            
public class Order
{
    public int Id { get; set; }
    public DateTime OrderDate { get; set; }
    public Customer Customer { get; set; }
}

If you are using .net core 3, then the above entity design will work perfectly, it will automatically find the matching columns with database object and allow you to save data just by setting public DbSet<Customer> tbCustomer { get; set; } in dbContext class.

However, if you are using earlier .net 4.5 frameworks, then the above entity design will throw exception, because it cannot figure out matching columns with database objects, so we need to explicitly specify the database table name with attribute [Table("tbCustomer")] like example below.

Also, if there is any additional property, which are not to be mapped with database columns , that also needs to be marked with [NotMapped] attribute.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

[Table("tbCustomer")]
public class Customer            
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime RegDate { get; set; }

    [NotMapped]
    public List<Order> Orders { get; set; }
}
           

Note: each property data type must be compatible with database column data type, otherwise framework will throw exception.

You may learn how to define complex object design and entity relation in entity framework core.

Define DBContext Class

Step 2: Create DBContext Class.

Here we have created AppDBContext you can give any name, but the class should be inherited from DbContext class under System.Data.Entity namespace

using System;
using System.Data.Entity;
public class AppDBContext:DbContext, IDisposable
{
    static string secureConnectionString = Util.PlainConnectionString;
    public AppDBContext()
    : base(secureConnectionString)
    {
    }
    public DbSet<Customer> tbCustomer { get; set; }
    public DbSet<Order> tbOrder { get; set; }
}

Above content class will work perfectly in .net core 3.0 framework, but if you are using earlier framework, you need to specify key column name for each entity, also specify if any property to be ignored, let’s look at the example below.

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public class AppDBContext:DbContext, IDisposable
{
static string secureConnectionString = Util.PlainConnectionString;
public AppDBContext()
: base(secureConnectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<tbCustomer>().HasKey(s => s.Id);
modelBuilder.Entity<tbCustomer>().Ignore(s => s.Orders);
modelBuilder.Entity<Order>().HasKey(s => s.OrderId);
}
    
}

Notice, how to specify the key column name for each entity using .HasKey(s => s.Id), and how to ignore all non-mapping property using .Ignore(s => s.Orders).

Database Connection Details

Step 3: Set up database connection details, here we have created a static string property that will read information from appsetting section of web config file.

internal class Util
{
    public static string PlainConnectionString
    {
        get
        {
            SqlConnectionStringBuilder providerCs = new SqlConnectionStringBuilder();
            providerCs.InitialCatalog = ConfigurationManager.AppSettings["DatabaseName"];
            providerCs.UserID = ConfigurationManager.AppSettings["UserId"];
            providerCs.Password = ConfigurationManager.AppSettings["Password"];
            providerCs.DataSource = ConfigurationManager.AppSettings["ServerName"];
            providerCs.MultipleActiveResultSets = true;
            providerCs.TrustServerCertificate = false;

            return providerCs.ToString();
        }
    }
}

Set up connection details in web.config

<appSettings>
<add key="ServerName" value="server_name" />
<add key="DatabaseName" value="database_name" />
<add key="SchemaName" value="dbo" />
<add key="UserId" value="db_user_name" />
<add key="Password" value="db_password" />
</appSettings>
Work with Database

Step 4: Write a DTO method to add and select data (you can write any functionality).

public class DbDto            
{
    public void AddSampleCustomer()
    {
    Customer cust = new Customer();
    cust.Id = 1;
    cust.Email = "webtrainingroom@gmail.com";
    cust.FullName = "WebTrainingRoom";
    cust.Phone = "90000000";
    cust.RegDate = DateTime.Now;
    cust.Orders = new List<Order>();
            
        using (AppDBContext context = new AppDBContext())
        {
        context.tbCustomer.Add(cust);
        context.SaveChanges();
        }
    }
            
    public List<Customer> getAllCustomers()
    {
    List<Customer> customers = null;
        using (AppDBContext context = new AppDBContext())
        {
        customers = context.tbCustomer
        .ToList<Customer>();
        }
    return customers;
    }            
}

Step 5: Add a simple web page to test the functionality, here in example we have added one gridview and a button , to create same sample data for testing .

Code in AspX page

// to display data
<asp:GridView ID="gvCustomer" runat="server">
</asp:GridView>
// to generate same sample data
<asp:Button ID="btnAdd" runat="server" Text="Add Sample Data" OnClick="btnAdd_Click" />

Code in Aspx Code behind

public partial class _Default : Page            
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        loadCustomerData();
    }
            
    void loadCustomerData()
    {
        DbDto dto = new DbDto();
        gvCustomer.DataSource = dto.getAllCustomers();
        gvCustomer.DataBind();
        dto = null;
    }
            
    protected void btnAdd_Click(object sender, EventArgs e)
    {
        DbDto dto = new DbDto();
        dto.AddSampleCustomer();
        dto = null;
    }
}

Result : from C# code, database object will be created and data will be inserted and fetched.

This was an example that we have worked with Aspx form the same way code first approach can be implemented with Asp.net MVC

you may be interested to read following posts!

 
Code First in Entity Framework

Learn entity framework orm using c#, entity framework core and earlier version of entity framework, all tutorials are written in c#.
Entity Framework Interview Questions

SQL interview questions
Entity Framework C# Examples | Join .Net C# Course