Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core 7
С помощью Fluent API мы можем задать многочисленные настройки для моделей и их свойств. Однако, если настроек очень много, то они могут утяжелять класс контекста. Однако в Entity Framework Core мы можем вынести конфигурацию моделей в отдельные классы.
Для вынесения конфигурации во вне необходимо создать класс конфигурации, реализующий интерфейс EntityTypeConfiguration<T>.
К примеру, пусть у нас есть следующий класс контекста и моделей:
public class ApplicationContext : DbContext { public DbSet<Company> Companies { get; set; } public DbSet<Product> Products { get; set; } public ApplicationContext() { Database.EnsureDeleted(); Database.EnsureCreated(); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=mobileappdb;Trusted_Connection=True;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Product>() .ToTable("Mobiles").HasKey(p => p.Ident); modelBuilder.Entity<Product>() .Property(p => p.Name).IsRequired().HasMaxLength(30); modelBuilder.Entity<Company>().ToTable("Manufacturers") .Property(c => c.Name).IsRequired().HasMaxLength(30); } } public class Company { public int Id { get; set; } public string Name { get; set; } } public class Product { public int Ident { get; set; } public string Name { get; set; } public int Price { get; set; } }
Вся конфигурация здесь определена в методе OnModelCreating(). В принципе он не содержит много кода, однако при наличии гораздо большего количества сущностей и более изощренной их конфигурации с помощью Fluent API данный метод мог бы сильно раздуться в размерах. И теперь изменим определение контекста, применив конфигурации:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System.Collections.Generic; public class ApplicationContext : DbContext { public DbSet<Company> Companies { get; set; } public DbSet<Product> Products { get; set; } public ApplicationContext() { Database.EnsureDeleted(); Database.EnsureCreated(); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=mobileappdb;Trusted_Connection=True;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new ProductConfiguration()); modelBuilder.ApplyConfiguration(new CompanyConfiguration()); } } public class ProductConfiguration : IEntityTypeConfiguration<Product> { public void Configure(EntityTypeBuilder<Product> builder) { builder.ToTable("Mobiles").HasKey(p => p.Ident); builder.Property(p => p.Name).IsRequired().HasMaxLength(30); } } public class CompanyConfiguration : IEntityTypeConfiguration<Company> { public void Configure(EntityTypeBuilder<Company> builder) { builder.ToTable("Manufacturers").Property(c => c.Name).IsRequired().HasMaxLength(30); } }
Теперь конфигурация моделей вынесена в отдельные классы. А для добавления конкретных конфигураций в контекст используется метод modelBuilder.ApplyConfiguration(), которому передается нужный объект конфигурации. В итоге по своему действию первый и второй варианты контекста будут идентичны.
В качестве альтернативы мы могли бы использовать еще один вариант. Вместо выделения отдельных классов конфигураций определить конфигурацию в виде отдельных методов в том же классе контекста данных:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; public class ApplicationContext : DbContext { public DbSet<Company> Companies { get; set; } public DbSet<Product> Products { get; set; } public ApplicationContext() { Database.EnsureDeleted(); Database.EnsureCreated(); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=mobileappdb;Trusted_Connection=True;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Product>(ProductConfigure); modelBuilder.Entity<Company>(CompanyConfigure); } // конфигурация для типа Product public void ProductConfigure(EntityTypeBuilder<Product> builder) { builder.ToTable("Mobiles").HasKey(p => p.Ident); builder.Property(p => p.Name).IsRequired().HasMaxLength(30); } // конфигурация для типа Company public void CompanyConfigure(EntityTypeBuilder<Company> builder) { builder.ToTable("Manufacturers").Property(c => c.Name).IsRequired().HasMaxLength(30); } }
Здесь конфигурация определяется для каждого типа в отдельном методе, который в качестве параметра принимает объект EntityTypeBuilder<T>
.
Затем метод передается в вызов modelBuilder.Entity<T>()
для соответствующей модели.