DEV Community

Cover image for Entity Framework Core Code First
Mohammed Chami
Mohammed Chami

Posted on

1

Entity Framework Core Code First

Entity Framework Core: Code-First Approach and CRUD Operations

Entity Framework (EF) Core is a modern, lightweight, and extensible object-relational mapper (ORM) for .NET. It enables developers to work with databases using .NET objects, eliminating the need for most of the data-access code typically required. EF Core supports the code-first approach, where you define your database schema using C# classes and let EF Core handle the database creation and updates.


Key Features of EF Core

  1. Database Creation, Update, and Maintenance: EF Core can create and update the database schema based on your C# classes.
  2. LINQ Queries: Write type-safe queries using LINQ (Language Integrated Query) to retrieve data.
  3. Change Tracking: Automatically tracks changes to entities and persists them in the database.
  4. Schema Migrations: Easily evolve your database schema over time using migrations.

Supported Databases

EF Core works with a wide range of databases, including:

  • SQL Server
  • Azure SQL Database
  • SQLite
  • Azure Cosmos DB
  • MySQL
  • PostgreSQL
  • And other databases through a provider plugin API.

For a complete list of supported databases, refer to the official EF Core documentation.


Getting Started with EF Core Code-First

Step 1: Set Up Your Project

  1. Launch Visual Studio and create a new solution with a project.
  2. Add a Class Library named DataAccess to the solution. This library will contain your EF Core models and database context.

Step 2: Define Your Models

In the DataAccess library, create a folder (e.g., Models) and add two classes: Manufacturer and Product. These classes represent the entities in your database.

public class Manufacturer
{
    [Key]
    public int Id { get; set; }

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

    [StringLength(200)]
    public string Description { get; set; }

    public string ContactEmail { get; set; }
    public string ContactPhone { get; set; }

    public virtual ICollection<Product> Products { get; set; } = new List<Product>();
}
Enter fullscreen mode Exit fullscreen mode
public class Product
{
    [Key]
    public int Id { get; set; }

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

    [StringLength(500)]
    public string Description { get; set; }

    [Required]
    [Column(TypeName = "decimal(18,2)")]
    public decimal Price { get; set; }

    public int ManufacturerId { get; set; }

    [ForeignKey(nameof(ManufacturerId))]
    public virtual Manufacturer Manufacturer { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Install EF Core Packages

In the DataAccess library, install the following NuGet packages:

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer (or the provider for your database)
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Tools

You can install these packages via the NuGet Package Manager or the Package Manager Console:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Tools
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Database Context

In the DataAccess library, create a class that inherits from DbContext. This class will manage your entities and database interactions.

public class ApplicationDbContext : DbContext
{
    public DbSet<Manufacturer> Manufacturers { get; set; }
    public DbSet<Product> Products { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            @"Server=MED;Database=testDB;Integrated Security=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Manufacturer>()
            .HasMany(m => m.Products)
            .WithOne(p => p.Manufacturer)
            .HasForeignKey(p => p.ManufacturerId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}
Enter fullscreen mode Exit fullscreen mode

Connection String and Security:

  • A connection string contains the server name, database name, and security credentials.
  • Store connection strings securely using:
    • Environment Variables
    • Secret Manager Tool (for development)
    • Azure Key Vault (for production)

Step 5: Create and Apply Migrations

  1. Open the Package Manager Console in Visual Studio.
  2. Set the default project to DataAccess.
  3. Run the following commands:
   Add-Migration Initial
   Update-Database
Enter fullscreen mode Exit fullscreen mode
  • Add-Migration Initial generates the migration scripts.
  • Update-Database applies the migration to the database.

EF Core will create the Manufacturer and Product tables, as well as a __EFMigrationsHistory table to track migrations.


Step 6: Perform CRUD Operations

Now that the database is set up, you can perform CRUD operations using the ApplicationDbContext.

Adding a Manufacturer:

using (var db = new ApplicationDbContext())
{
    var manufacturer = new Manufacturer
    {
        Name = "Manu_Toys",
        Description = "Creates kids' toys"
    };

    db.Manufacturers.Add(manufacturer);
    db.SaveChanges();
}
Enter fullscreen mode Exit fullscreen mode

Reading Data:

using (var db = new ApplicationDbContext())
{
    var manufacturers = db.Manufacturers.ToList();
    foreach (var manufacturer in manufacturers)
    {
        Console.WriteLine($"Manufacturer: {manufacturer.Name}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Updating Data:

using (var db = new ApplicationDbContext())
{
    var manufacturer = db.Manufacturers.Find(1); // Find by Id
    if (manufacturer != null)
    {
        manufacturer.Description = "Updated description";
        db.SaveChanges();
    }
}
Enter fullscreen mode Exit fullscreen mode

Deleting Data:

using (var db = new ApplicationDbContext())
{
    var manufacturer = db.Manufacturers.Find(1); // Find by Id
    if (manufacturer != null)
    {
        db.Manufacturers.Remove(manufacturer);
        db.SaveChanges();
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

Note that this is just a simple example to show you EF Core Code First in a real project you would use the following:

  1. Use Dependency Injection: Inject DbContext into your services or controllers instead of creating instances manually.
  2. Async Operations: Use SaveChangesAsync and ToListAsync for better performance in web applications.
  3. Separate Concerns: Keep your data access logic in a separate layer (e.g., a repository pattern).

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay