Models and Migrations
In Entity Framework Core (EF Core), the process of persisting your application's data involves defining how your application's domain model maps to your database schema. EF Core provides powerful tools to manage this mapping and evolve your database schema over time using migrations.
Defining Your Models
Your application's domain model is represented by Plain Old CLR Objects (POCOs) that EF Core can understand. These classes will represent your database tables, and their properties will represent the columns.
Entity Classes
An entity class is a .NET class that represents a type of data that you'll be storing in your database. For example, a Product class:
// Models/Product.cs
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int StockCount { get; set; }
}
Navigation Properties
You can define relationships between entities using navigation properties. For instance, a Category with many Products:
// Models/Category.cs
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public ICollection Products { get; set; }
}
EF Core can automatically infer relationships based on these properties and conventions.
Introducing Migrations
Migrations are EF Core's way of incrementally updating your database schema to match your application's model. They allow you to track changes and apply them consistently across different development environments and to production.
Enabling Migrations
First, you need to install the necessary EF Core tools. Open the Package Manager Console (Tools > NuGet Package Manager > Package Manager Console) and run:
Install-Package Microsoft.EntityFrameworkCore.Tools
Creating the First Migration
To create your first migration, which will capture your initial model and create the corresponding database schema, run the following command in the Package Manager Console:
Add-Migration InitialCreate
This will create two files in a new Migrations folder:
- A timestamped migration file (e.g.,
20231027100000_InitialCreate.cs) containing the code to create your tables. - A snapshot file (e.g.,
MyDbContextModelSnapshot.cs) representing your current model state.
Applying Migrations
To apply the pending migrations to your database, use the Update-Database command:
Update-Database
This command will execute the migration scripts against your configured database, creating the tables and schema defined by your models.
Generating a Model from an Existing Database (Reverse Engineering)
If you have an existing database, you can generate your EF Core models and DbContext from it. This is often done using the EF Core scaffolding tools. Ensure you have the appropriate database provider package installed (e.g., Microsoft.EntityFrameworkCore.SqlServer).
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=MyExistingDatabase;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
This command will generate entity classes and a DbContext in the specified output directory, allowing you to work with your existing database.
Tip: Regularly run Add-Migration after making model changes and Update-Database to keep your database schema synchronized. This workflow is crucial for maintaining data integrity and facilitating collaboration.
Configuring the DbContext
Your DbContext is the bridge between your application and your data. You'll configure it to represent your database session and map your entity sets.
// Data/MyDbContext.cs
using Microsoft.EntityFrameworkCore;
using YourApp.Models;
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions options) : base(options) { }
public DbSet Products { get; set; }
public DbSet Categories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure relationships, primary keys, etc. here if not using conventions
modelBuilder.Entity()
.HasKey(p => p.ProductId);
modelBuilder.Entity()
.HasKey(c => c.CategoryId);
modelBuilder.Entity()
.HasMany(c => c.Products)
.WithOne(); // Assuming no explicit navigation property back from Product to Category here
base.OnModelCreating(modelBuilder);
}
}
This DbContext can then be registered with the dependency injection container in your Startup.cs or Program.cs file.
Understanding how to define your models and manage your database schema with migrations is a fundamental skill when working with Entity Framework Core in ASP.NET Core applications. It ensures a robust and maintainable data persistence layer.