Язык программирования C#9 и платформа .NET5
<b>KEY([CarId])</b><b>REFERENCES [dbo].[Cars] ([Id])</b><b>ON DELETE CASCADE</b>GO<b>ALTER TABLE [dbo].[Radios] CHECK CONSTRAINT [FK_Radios_Cars_CarId]</b>GOОбратите внимание на ограничения внешнего ключа и проверки, созданные для зависимой таблицы (
).RadiosОтношения "многие ко многим" (нововведение в версии EF Core 5)
В отношении "многие ко многим" каждая сущность содержит навигационное свойство типа коллекции для другой сущности, что в хранилище данных реализуется с использованием таблицы соединения посреди двух сущностных таблиц. Такая таблица соединения именуется в соответствии с двумя таблицами в виде
. Имя можно изменить в коде через Fluent API. Таблица соединения имеет отношения "один ко многим" с каждой сущностной таблицей:<Сущность1Сущность2>namespace AutoLot.Samples.Models{public class Car : BaseEntity{public string Color { get; set; }public string PetName { get; set; }public int MakeId { get; set; }public Make MakeNavigation { get; set; }public Radio RadioNavigation { get; set; }<b> public IEnumerable<Driver> Drivers { get; set; } = new List<Driver>();</b>}}namespace AutoLot.Samples.Models{public class Driver : BaseEntity{public string FirstName { get; set; }public string LastName { get; set; }<b> public IEnumerable<Car> Cars { get; set; } = new List<Car>();</b>}}Эквивалентное решение можно обеспечить путем явного создания трех таблиц и именно так приходилось поступать в версиях EF Core, предшествующих EF Core 5. Вот как выглядит сокращенный пример:
public class Driver{...<b> public IEnumerable<CarDriver> CarDrivers { get; set; }</b>}public class Car{...<b> public IEnumerable<CarDriver> CarDrivers { get; set; }</b>}public class CarDriver{public int CarId {get;set;}<b> public Car CarNavigation {get;set;}</b>public int DriverId {get;set;}<b> public Driver DriverNavigation {get;set;}</b>}Добавьте в класс
экземплярApplicationDbContext:DbSet<Driver>public virtual DbSet<Car> Cars { get; set; }public virtual DbSet<Make> Makes { get; set; }<b>public virtual DbSet<Radio> Radios { get; set; }</b><b>public virtual DbSet<Driver> Drivers { get; set; }</b>Создайте миграцию и обновите базу данных с помощью следующих команд:
dotnet ef migrations add Many2Many -o Migrations-c AutoLot.Samples.ApplicationDbContextdotnet ef database update many2Many -c AutoLot.Samples.ApplicationDbContextПосле обновления базы данных с применением миграции EF Core таблица
не изменяется, но создаются таблицыCarsиDrivers:CarDriverCREATE TABLE [dbo].[Drivers]([Id] [INT] IDENTITY(1,1) NOT NULL,[FirstName] [NVARCHAR](MAX) NULL,[LastName] [NVARCHAR](MAX) NULL,[TimeStamp] [VARBINARY](MAX) NULL,CONSTRAINT [PK_Drivers] PRIMARY KEY CLUSTERED([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS= ON, ALLOW_PAGE_LOCKS = ON,OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GOCREATE TABLE [dbo].[CarDriver]([CarsId] [int] NOT NULL,[DriversId] [int] NOT NULL,<b>CONSTRAINT [PK_CarDriver] PRIMARY KEY CLUSTERED</b><b>(</b><b> [CarsId] ASC,</b><b> [DriversId] ASC</b><b>)</b>WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS= ON, ALLOW_PAGE_LOCKS = ON,