Язык программирования C#9 и платформа .NET5
dotnet ef database drop -f -c AutoLot.Samples.ApplicationDbContextНавигационные свойства и внешние ключи
Навигационные свойства представляют то, каким образом сущностные классы связаны между собой, и позволяют проходить от одного экземпляра сущности к другому. По определению навигационным является любое свойство, которое отображается на нескалярный тип, как определено поставщиком базы данных. На практике навигационное свойство сопоставляется с другой сущностью (навигационное свойство типа ссылки) или с коллекцией других сущностей (навигационное свойство типа коллекций). На стороне базы данных навигационные свойства транслируются в отношения внешнего ключа между таблицами. Инфраструктура EF Core напрямую поддерживает отношения вида "один к одному", "один ко многим" и (в версии EF Core 5) "многие ко многим". Сущностные классы также могут иметь обратные навигационные свойства с самими собой, представляя самоссылающиеся таблицы.
На заметку! Объекты с навигационными свойствами удобно рассматривать как связные списки. Если навигационные свойства являются двунаправленными, тогда объекты ведут себя подобно двусвязным спискам.
Прежде чем погружаться в детали навигационных свойств и шаблонов отношений между сущностями, ознакомьтесь с табл. 22.4, где приведены термины, которые используются во всем трех шаблонах отношений.
Отсутствие свойств для внешних ключей
Если сущность с навигационным свойством типа ссылки не имеет свойства для значения внешнего ключа, тогда EF Core создаст необходимое свойство или свойства внутри сущности. Они известны как теневые свойства внешних ключей и именуются в формате
или<имя навигационного свойства><имя свойства главного ключа>. Сказанное справедливо для всех видов отношений ("один ко многим", "один к одному", "многие ко многим"). Такой подход к построению сущностей с явным свойством или свойствами внешних ключей гораздо яснее, чем поручение их создания исполняющей среде EF Core.<имя главной сущности><имя свойства главного ключа>Отношения "один ко многим"
Чтобы создать отношение "один ко многим", сущностный класс со стороны "один" (главная сущность) добавляет свойство типа коллекции сущностных классов, находящихся на стороне "многие" (зависимые сущности). Зависимая сущность также должна иметь свойства для внешнего ключа обратно к главной сущности, иначе исполняющая среда EF Core создаст теневые свойства внешних ключей, как объяснялось ранее.
Например, в базе данных, созданной в главе 21, между таблицей
(представленной сущностным классомMakes) и таблицейMake(представленной сущностным классомInventory) имеется отношение "один ко многим". Для упрощения примеров сущностьCarбудет отображаться на таблицуCar. В следующем коде показаны двунаправленные навигационные свойства, представляющие это отношение:Carsusing System.Collections.Generic;namespace AutoLot.Samples.Models{public class Make : BaseEntity{public string Name { get; set; }<b> public IEnumerable<Car> Cars { get; set; } = new List<Car>();</b>}}using System.Collections.Generic;namespace AutoLot.Samples.Models{public class Car : BaseEntity{public string Color { get; set; }public string PetName { get; set; }<b> public int MakeId { get; set; }</b><b> public Make MakeNavigation { get; set; }</b>}}На заметку! При создании шаблонов для существующей базы данных исполняющая среда EF Core именует навигационные свойства типа ссылок аналогично обычным свойствам (скажем,
). В итоге могут возникать проблемы с навигацией иpublic Make {get; set;}, не говоря уже о затруднениях при работе с кодом. Для ясности предпочтительнее добавлять к именам навигационных свойств типа ссылок суффиксIntelliSense, как демонстрировалось выше.NavigationВ примере
сущностьCar/Makeявляется зависимой ("многие" в "один ко многим"), а сущностьCar— главной ("один" в "один ко многим").MakeДобавьте в класс
экземплярApplicationDbContext:DbSet<Make>public DbSet<Car> Cars { get; set; }<b>public DbSet<Make> Makes { get; set; }</b>Затем создайте миграцию и обновите базу данных с использованием приведенных далее команд:
dotnet ef migrations add One2Many -o Migrations-c AutoLot.Samples.ApplicationDbContextdotnet ef database update One2Many -c AutoLot.Samples.ApplicationDbContextПри обновлении базы данных с применением миграции EF Core создаются следующие таблицы:
CREATE TABLE [dbo].[Makes]([Id] [int] IDENTITY(1,1) NOT NULL,[Name] [nvarchar](max) NULL,[TimeStamp] [varbinary](max) NULL,CONSTRAINT [PK_Makes] PRIMARY KEY CLUSTERED([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS= ON, ALLOW_PAGE_LOCKS = ON,
