<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)
В отношении "многие ко многим" каждая сущность содержит навигационное свойство типа коллекции для другой сущности, что в хранилище данных реализуется с использованием таблицы соединения посреди двух сущностных таблиц. Такая таблица соединения именуется в соответствии с двумя таблицами в виде
<Сущность1Сущность2>
. Имя можно изменить в коде через Fluent API. Таблица соединения имеет отношения "один ко многим" с каждой сущностной таблицей:
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.ApplicationDbContext
dotnet ef database update many2Many -c AutoLot.Samples.ApplicationDbContext
После обновления базы данных с применением миграции EF Core таблица
Cars
не изменяется, но создаются таблицы
Drivers
и
CarDriver
:
CREATE 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]
GO
CREATE 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,