Asp.Net Core Code First Approach Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of ASP.NET Core Code First Approach

ASP.NET Core Code First Approach: Explained in Details with Important Information

1. Introduction

Entity Framework (EF) Core supports multiple workflows for application development, the most intuitive being the Code First workflow. In the Code First approach you begin by defining your data model via C#, which EF Core converts into a database schema. EF Core creates the database automatically in a development environment, making it incredibly convenient for rapid prototyping and agile development.

2. Benefits of Code First Approach

  • Rapid Development: Facilitates quick creation and evolution of models.
  • Database Evolution: Supports migrations, allowing the automatic update of your database during development.
  • Flexibility: Enables seamless integration with any kind of database supported by EF Core.
  • Simplified Design: Models are designed in code, making them easier to maintain across changes.
  • Testability: Models can be easily tested independently using mock contexts.

3. Setting Up ASP.NET Core Project

To begin using the Code First approach, ensure that the following prerequisites are met:

  • Install Visual Studio or another compatible IDE.
  • Install the .NET SDK.
  • Use NuGet package manager to add Microsoft.EntityFrameworkCore.SqlServer (or the relevant database provider) to your project.
dotnet add package Microsoft.EntityFrameworkCore.SqlServer

4. Defining Models

Develop your model classes. These classes are used to define the structure of the tables in your database. Each class typically represents an entity mapped to a table.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public List<Post> Posts { get; set; } = new List<Post>();
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

5. Creating DbContext

Create a class that inherits from DbContext. This class represents a session with your database and is responsible for executing queries and saving instances of your models to the database.

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Data Source=(localdb)\\mssqllocaldb;Initial Catalog=Blogging;Integrated Security=True");
    }
}

In the OnConfiguring method, configure your database connection string. Alternatively, override OnModelCreating to configure relationships, indexes, and more.

6. Configuring Relationships

Define relationships between entities using navigation properties and configure keys and constraints in the OnModelCreating method.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(b => b.Posts)
        .WithOne(p => p.Blog)
        .HasForeignKey(p => p.BlogId);
}

This configuration sets up a one-to-many relationship between Blog and Post, with each post containing a foreign key BlogId.

7. Migrations

Migrations allow EF Core to evolve your database schema in sync with changes to your model classes. To add a migration, use the Entity Framework Core CLI tools or Visual Studio.

dotnet ef migrations add InitialCreate

This command adds a new migration to your project that contains the necessary SQL to create the database based on your current model.

Run the migration to the database:

dotnet ef database update

8. Seeding Data

You can seed initial data into your database when it's created.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().HasData(
        new Blog { BlogId = 1, Url = "http://example.com/blog1" },
        new Blog { BlogId = 2, Url = "http://example.com/blog2" }
    );
}

9. Reading Data

Use LINQ to query data from your database.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.Include(blog => blog.Posts).ToList();
}

Here, the Include method is used to specify eager loading, ensuring that related Post entities are retrieved along with Blog entities.

10. Adding New Data

Insert new data into the database.

using (var context = new BloggingContext())
{
    var blog = new Blog { Url = "http://example.com/blog3" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

The Add method stages the object for insertion, and SaveChanges commits the transaction to the database.

11. Updating Existing Data

Modify existing records.

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    if (blog != null)
    {
        blog.Url = "http://updatedurl.com";
        context.SaveChanges();
    }
}

The Find method locates an entity with the specified primary key. Once retrieved, modifications to the entity are tracked by DbContext and saved with SaveChanges.

12. Deleting Data

Remove existing records from the database.

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    if (blog != null)
    {
        context.Blogs.Remove(blog);
        context.SaveChanges();
    }
}

The Remove method marks an entity as deleted, and SaveChanges applies these deletions to the database.

13. Conventions

EF Core follows conventions to determine how model classes should be mapped to database tables. For example, properties named Id or <ClassName>Id are used as primary keys by default.

14. Data Annotations

Decorate model properties with attributes to override default conventions. Common annotations include Key, Required, StringLength, etc.

public class Post
{
    [Key]
    public int PostId { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; }

    public string Content { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

15. Customizing Model Configuration

For more complex scenarios, use the Fluent API to configure your model properties explicitly within the OnModelCreating method.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .IsRequired();

    modelBuilder.Entity<Post>()
        .Property(p => p.Title)
        .HasMaxLength(100)
        .IsRequired();
}

16. Handling Multiple Contexts

It's possible to have multiple contexts in a project, each representing different parts or sections of your database. Ensure that each context manages its own scope of models.

17. Database Initialization

Control the initialization behavior of your database using strategies like EnsureCreated, EnsureDeleted, or Database.Migrate.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    using (var db = new BloggingContext())
    {
        db.Database.EnsureCreated(); // Creates database if not exists
        db.Database.Migrate();       // Applies migrations if any exists
    }
}

18. Advanced Scenarios

Consider using features like shadow properties, backing fields, and model splitting for advanced requirements beyond the basics.

Shadow Properties

Used to track state without adding a property to the entity class.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property<DateTime>("LastUpdated")
        .HasDefaultValueSql("GETDATE()");
}
Backing Fields

Allow private fields in your entity class to store data rather than relying solely on properties.

private string _title;

public string Title
{
    get => _title;
    set => _title = value;
}

Configure backing fields in OnModelCreating:

modelBuilder.Entity<Post>()
    .Property(p => p.Title)
    .HasField("_title")
    .UsePropertyAccessMode(PropertyAccessMode.Field);
Model Splitting

Split a single entity type into multiple classes.

[Owned]
public class Address
{
    public string StreetAddress { get; set; }
    public string City { get; set; }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    
    private Address _address;
    public Address Address
    {
        get => _address ??= new Address();
        set => _address = value;
    }
}

19. Troubleshooting

If issues arise, common areas to check include:

  • Properly configuring the DbContext.
  • Ensuring that all NuGet packages are correctly installed and updated.
  • Correctly applying migrations using dotnet ef database update.
  • Verifying database permissions and availability.
  • Handling exceptions thrown by DbContext methods.

20. Documentation and Resources

Refer to official Microsoft documentation for extensive guidance, tutorials, and best practices:

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement ASP.NET Core Code First Approach

Step 1: Set Up Your Environment

  • Install .NET SDK: Make sure you have the .NET SDK installed on your machine. You can download it from here.
  • Install SQL Server: You need a SQL Server instance. You can use SQL Server Express, which is free, or you can use the SQL Server in the cloud with Azure.
  • Visual Studio (Optional): Installing Visual Studio is recommended for an integrated development environment. You can download it here (free Community edition is sufficient).

Step 2: Create a New ASP.NET Core Web Application

  1. Open Terminal/Command Prompt: Navigate to the directory where you want to create your project.

  2. Create a New Project: Run the following command to create a new ASP.NET Core Web Application project.

    dotnet new mvc -n CodeFirstExample
    

    This command creates a new MVC project named CodeFirstExample.

  3. Navigate to the Project Directory:

    cd CodeFirstExample
    

Step 3: Install Entity Framework Core

  1. Install Entity Framework NuGet Packages:
    dotnet add package Microsoft.EntityFrameworkCore.SqlServer
    dotnet add package Microsoft.EntityFrameworkCore.Tools
    dotnet add package Microsoft.EntityFrameworkCore.Design
    

Step 4: Define Your Data Model

  1. Create a New Folder: Create a folder named Models in your project directory.

  2. Create a Model Class: Inside the Models folder, create a new class named Product.cs.

    // Models/Product.cs
    namespace CodeFirstExample.Models
    {
        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public decimal Price { get; set; }
            public int Stock { get; set; }
        }
    }
    

Step 5: Set Up the DbContext

  1. Create a New Folder: Create a folder named Data in your project directory.

  2. Create a DbContext Class: Inside the Data folder, create a new class named ApplicationDbContext.cs.

    // Data/ApplicationDbContext.cs
    using Microsoft.EntityFrameworkCore;
    using CodeFirstExample.Models;
    
    namespace CodeFirstExample.Data
    {
        public class ApplicationDbContext : DbContext
        {
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
                : base(options)
            {
            }
    
            public DbSet<Product> Products { get; set; }
        }
    }
    

Step 6: Configure Services

  1. Configure Services in Program.cs: In ASP.NET Core 6+, you configure services in the Program.cs file.

    // Program.cs
    using Microsoft.EntityFrameworkCore;
    using CodeFirstExample.Data;
    
    var builder = WebApplication.CreateBuilder(args);
    
    

// Add services to the container. builder.Services.AddControllersWithViews();

// Register the DbContext with DI container string connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => options.UseSqlServer(connectionString));

var app = builder.Build();

// Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); }

app.UseHttpsRedirection(); app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run(); ```

  1. Add Connection String to appsettings.json:

    {
        "ConnectionStrings": {
            "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=CodeFirstExampleDb;Integrated Security=True;"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning"
            }
        },
        "AllowedHosts": "*"
    }
    

Step 7: Create Migrations

  1. Add Initial Migration:

    dotnet ef migrations add InitialCreate
    
  2. Update Database:

    dotnet ef database update
    

This will create a new SQL Server database CodeFirstExampleDb and a Products table based on your Product model.

Step 8: Create a Controller and Views

  1. Create a Controller: Use scaffolding to create a controller and views for the Product model.

    dotnet aspnet-codegenerator controller -name ProductsController -m Product -dc ApplicationDbContext --relativeFolderPath Controllers --useDefaultLayout --referenceScriptLibraries
    

This command will create a ProductsController and corresponding views.

  1. Run the Application: Start your application by running:

    dotnet run
    

Navigate to /Products in your browser to see the list of products, create new ones, and manage existing products.

Summary

  • Set up a new ASP.NET Core MVC project.
  • Define a data model (Product).
  • Set up DbContext (ApplicationDbContext).
  • Configure the project to use Entity Framework Core with SQL Server.
  • Create migrations and update the database.
  • Scaffold a controller and views for CRUD operations.

Top 10 Interview Questions & Answers on ASP.NET Core Code First Approach

1. What is the ASP.NET Core Code First Approach?

Answer: The ASP.NET Core Code First Approach is a development technique where you begin with your model classes and Entity Framework Core (EF Core) uses these classes to create the database. This approach is also known as the "Code First" methodology, and it provides a flexible way to design and develop databases with minimal manual intervention. In essence, it enables developers to focus on their application’s domain model, and the framework handles the database schema creation and modifications.

2. How do I set up a project using the Code First Approach in ASP.NET Core?

Answer: To set up a project using the Code First Approach, follow these steps:

  1. Create a new ASP.NET Core Web Application:

    • Open Visual Studio and create a new project.
    • Choose "ASP.NET Core Web Application" and click "Next."
    • Provide a project name and click "Create."
    • Choose "Web Application (Model-View-Controller)" or another template according to your needs and click "Create."
  2. Install Entity Framework Core Packages:

    • Open the NuGet Package Manager and install Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer packages.
  3. Define Your Model:

    • Create classes that represent the tables in your database.
    • Example:
      public class Blog
      {
          public int BlogId { get; set; }
          public string Url { get; set; }
      }
      
  4. Create a DbContext:

    • Define a class derived from DbContext that includes DbSet properties for the models.
    • Example:
      public class BloggingContext : DbContext
      {
          public BloggingContext(DbContextOptions<BloggingContext> options)
              : base(options)
          {
          }
      
          public DbSet<Blog> Blogs { get; set; }
      }
      
  5. Configure the DbContext:

    • In the Startup.cs file (or Program.cs for newer versions), add the connection string and configure the DbContext to use SQL Server.
    • Example:
      builder.Services.AddDbContext<BloggingContext>(options =>
          options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
      
  6. Create Migrations and Update the Database:

    • Use the .NET CLI to create initial migrations:
      dotnet ef migrations add InitialCreate
      
    • Update the database:
      dotnet ef database update
      

3. What are the advantages of using the Code First Approach?

Answer: The Code First Approach offers several advantages:

  • Flexibility: Easily modify the model classes and update the database schema.
  • Consistency: Keep the application domain model and database schema in sync.
  • Rapid Development: Allows for quick iterations without the need for database-first design.
  • Testability: Easier to mock and unit test the application logic without a real database.
  • Agility: Enables faster response to changing business requirements.

4. How do you handle data migrations with the Code First Approach?

Answer: Data migrations with the Code First Approach are managed through EF Core migrations. Here’s how you can create and apply migrations:

  1. Create a Migration:

    • Run the following command in the Package Manager Console or .NET CLI to create a new migration:
      dotnet ef migrations add MigrationName
      
  2. Apply Migrations:

    • To update the database schema with the new migration, execute:
      dotnet ef database update
      
  3. Reverse Engineering Migrations:

    • If you have changes in the database, you can scaffold a migration:
      dotnet ef migrations scaffold InitialCreate
      
  4. Roll Back Migrations:

    • You can roll back the last migration using:
      dotnet ef database update 0
      
  5. View Migration Scripts:

    • Migration scripts are created in the Migrations folder and can be reviewed and modified if necessary.

5. Can I modify existing classes to add new properties?

Answer: Yes, you can modify existing model classes to add new properties. Once you add a new property, you need to create a new migration and apply it to update the database schema. Here’s how you can do it:

  1. Add a new property to a class:

    • For example, adding a Name property to the Blog class:
      public class Blog
      {
          public int BlogId { get; set; }
          public string Url { get; set; }
          public string Name { get; set; } // New property
      }
      
  2. Create a new migration:

    • Run:
      dotnet ef migrations add AddBlogName
      
  3. Apply the migration:

    • Execute:
      dotnet ef database update
      

6. How do you remove a class or property from the model?

Answer: Removing a class or property from the model requires careful handling to avoid data loss. Here’s how you can do it:

  1. Remove the class or property from the model:

    • Ensure that the removal does not result in data loss, especially if the property contains data that needs to be preserved.
    • Example, removing a property from the Blog class:
      public class Blog
      {
          public int BlogId { get; set; }
          public string Url { get; set; }
          // public string Name { get; set; } - Removed
      }
      
  2. Create a new migration:

    • Run:
      dotnet ef migrations add RemoveBlogName
      
  3. Apply the migration:

    • Execute:
      dotnet ef database update
      
  4. Consider data backup:

    • Before removing a class or property, consider backing up relevant data if necessary.

7. How do you configure EF Core relationships in the Code First Approach?

Answer: EF Core supports various types of relationships, including one-to-one, one-to-many, and many-to-many. Here’s an example of how to configure a one-to-many relationship:

  1. Define the model classes:

    • Example classes Blog and Post with a one-to-many relationship:
      public class Blog
      {
          public int BlogId { get; set; }
          public string Url { get; set; }
          public List<Post> Posts { get; set; }
      }
      
      public class Post
      {
          public int PostId { get; set; }
          public string Title { get; set; }
          public string Content { get; set; }
      
          public int BlogId { get; set; }
          public Blog Blog { get; set; }
      }
      
  2. Configure relationships in DbContext:

    • Use OnModelCreating method in DbContext to configure relationships:
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Blog>()
              .HasMany(b => b.Posts)
              .WithOne(p => p.Blog)
              .HasForeignKey(p => p.BlogId);
      }
      

8. Can I use Fluent API to configure model relationships?

Answer: Yes, the Fluent API provides a powerful way to configure model relationships in EF Core. It allows for customization of relationships that cannot be easily achieved with data annotations. Here’s an example using Fluent API:

  1. Define model classes:

    • Example with Blog and Post classes:
      public class Blog
      {
          public int BlogId { get; set; }
          public string Url { get; set; }
          public List<Post> Posts { get; set; }
      }
      
      public class Post
      {
          public int PostId { get; set; }
          public string Title { get; set; }
          public string Content { get; set; }
      
          public Blog Blog { get; set; }
      }
      
  2. Configure relationships using Fluent API:

    • Override OnModelCreating method in DbContext:
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Blog>()
              .HasMany(b => b.Posts)
              .WithOne(p => p.Blog)
              .HasForeignKey(p => p.BlogId);
      }
      
  3. Advanced configurations:

    • Configure more complex relationships and constraints:
      modelBuilder.Entity<Blog>()
          .HasMany(b => b.Posts)
          .WithOne(p => p.Blog)
          .HasForeignKey(p => p.BlogId)
          .OnDelete(DeleteBehavior.Cascade);
      

9. How can I handle seeding data with the Code First Approach?

Answer: Seeding data in the Code First Approach involves populating your database with initial data. Here’s how you can do it:

  1. Override the OnModelCreating method:

    • Use the HasData method to add seed data.
    • Example:
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Blog>().HasData(
              new Blog { BlogId = 1, Url = "http://example.com/blog1" }
          );
      
          modelBuilder.Entity<Post>().HasData(
              new Post { PostId = 1, BlogId = 1, Title = "First post", Content = "This is the first post." }
          );
      }
      
  2. Create and Apply Migrations:

    • Create a migration to apply seed data changes:
      dotnet ef migrations add SeedData
      
    • Update the database:
      dotnet ef database update
      
  3. Considerations:

    • Ensure that seeding data runs only once and does not overwrite existing data unless intended.

10. What are some best practices when working with Code First in ASP.NET Core?

Answer: Here are some best practices for working with the Code First Approach in ASP.NET Core:

  1. Modularize Configuration:

    • Use the Fluent API to modularize configuration for better readability and maintainability.
  2. Use Data Annotations:

    • Leverage data annotations for simple configurations to reduce code in DbContext.
  3. Migrate Regularly:

    • Regularly create and apply migrations to keep the database schema in sync with the model.
  4. Backup Data:

    • Always back up your database before performing migrations, especially when removing data.
  5. Test Migrations in Development:

    • Test migrations in a development environment before deploying to production to avoid data loss.
  6. Use Environment-Specific Connection Strings:

    • Use environment variables or configuration files to manage connection strings for different environments.
  7. Document Changes:

    • Document all schema changes and migrations for future reference and troubleshooting.
  8. Optimize Database Performance:

    • Consider database performance and optimize queries and schema design as needed.
  9. Use Transactions:

    • Use transactions to ensure data consistency during database operations.
  10. Adopt a Version Control Strategy:

    • Use version control to manage migrations and ensure that changes are tracked and easily revertible.

You May Like This Related .NET Topic

Login to post a comment.