Конфигурация моделей

Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core 7

Последнее обновление: 16.11.2020

С помощью 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>() для соответствующей модели.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850