Настройка Entity Framework Core для .NET веб-застосунку
Entity Framework Core — основний ORM для .NET 6+. На відміну від класичного EF, EF Core написаний з нуля, підтримує PostgreSQL через Npgsql, працює без GAC та встановлюється як NuGet-пакет.
Встановлення
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef
DbContext
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<User> Users => Set<User>();
public DbSet<Product> Products => Set<Product>();
public DbSet<Order> Orders => Set<Order>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
modelBuilder.Entity<Product>()
.HasQueryFilter(p => !p.IsDeleted);
}
}
DI Реєстрація
builder.Services.AddDbContext<AppDbContext>(options =>
{
options.UseNpgsql(
builder.Configuration.GetConnectionString("Default"),
npgsqlOptions =>
{
npgsqlOptions.CommandTimeout(30);
npgsqlOptions.EnableRetryOnFailure(maxRetryCount: 3);
}
);
});
Модель
public class Product
{
public int Id { get; set; }
public string Title { get; set; } = default!;
public string Slug { get; set; } = default!;
public decimal Price { get; set; }
public ProductStatus Status { get; set; } = ProductStatus.Draft;
public int CategoryId { get; set; }
public Category Category { get; set; } = default!;
public ICollection<Tag> Tags { get; set; } = new List<Tag>();
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
Конфігурація
public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.ToTable("products");
builder.HasKey(p => p.Id);
builder.Property(p => p.Title).HasMaxLength(500).IsRequired();
builder.Property(p => p.Slug).HasMaxLength(520).IsRequired();
builder.HasIndex(p => p.Slug).IsUnique();
builder.HasOne(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasMany(p => p.Tags)
.WithMany(t => t.Products)
.UsingEntity(j => j.ToTable("product_tags"));
}
}
Запити
public async Task<List<Product>> GetPublishedAsync(
int categoryId,
int page = 1,
int pageSize = 24,
CancellationToken ct = default)
{
return await _db.Products
.AsNoTracking()
.Include(p => p.Category)
.Include(p => p.Tags)
.Where(p => p.CategoryId == categoryId && p.Status == ProductStatus.Published)
.OrderByDescending(p => p.CreatedAt)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync(ct);
}
Міграції
dotnet ef migrations add CreateProducts
dotnet ef database update
dotnet ef migrations script --idempotent --output migrations.sql
Терміни
Первісна настройка EF Core: 1 день. Оптимізація: 1–2 дні.







