Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
@p9 nvarchar(50),@p10 int,@p11 nvarchar(50)',@p0=N'Yellow',@p1=1,@p2=N'Herbie',@p3=N'White',@p4=2,@p5=N'Mach 5',@p6=N'Pink',@p7=3,@p8=N'Avon',@p9=N'Blue',@p10=4,@p11=N'Blueberry'Принадлежащие сущностные типы
Возможность применения класса C# в качестве свойства сущности с целью определения коллекции свойств для другой сущности впервые появилась в версии EF Core 2.0 и в последующих версиях постоянно обновлялась. Когда типы, помеченные атрибутом
[Owned][Owned]"За кулисами" EF Core считает результат отношением "один к одному". Принадлежащий класс является зависимой сущностью, а владеющий класс — главной сущностью. Хотя принадлежащий класс рассматривается как сущность, он не может существовать без владеющего класса. Имена столбцов из принадлежащего класса по умолчанию получают формат
ИмяНавигационногоСвойства_ИмяСвойстваПринадлежащейСущностиPersonalNavigation_FirstNameВзгляните на приведенный далее класс Person (обратите внимание на атрибут
[Owned]<b>[Owned]</b>public class Person{ [Required, StringLength(50)] public string FirstName { get; set; } = "New"; [Required, StringLength(50)] public string LastName { get; set; } = "Customer";}Он используется классом
Customer[Table("Customers", Schema = "Dbo")]public partial class Customer : BaseEntity{ public Person PersonalInformation { get; set; } = new Person(); [JsonIgnore] [InverseProperty(nameof(CreditRisk.CustomerNavigation))] public IEnumerable<CreditRisk> CreditRisks { get; set; } = new List<CreditRisk>(); [JsonIgnore] [InverseProperty(nameof(Order.CustomerNavigation))] public IEnumerable<Order> Orders { get; set; } = new List<Order>();}По умолчанию два свойства
PersonPersonalInformation_FirstNamePersonalInformation_LastNameOnConfiguring()modelBuilder.Entity<Customer>(entity =>{ entity.OwnsOne(o => o.PersonalInformation, pd => { pd.Property<string>(nameof(Person.FirstName)) .HasColumnName(nameof(Person.FirstName)) .HasColumnType("nvarchar(50)"); pd.Property<string>(nameof(Person.LastName)) .HasColumnName(nameof(Person.LastName)) .HasColumnType("nvarchar(50)"); });});Вот как будет создаваться результирующая таблица (обратите внимание, что допустимость значений
nullFirstNameLastNamePersonCREATE TABLE [dbo].[Customers]( [Id] [int] IDENTITY(1,1) NOT NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [TimeStamp] [timestamp] NULL, [FullName] AS (([LastName]+', ')+[FirstName]),CONSTRAINT [PK_Customers] 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]GOПроблема с принадлежащими сущностями, которая может быть не видна вам, но приводить к сложной ситуации, в версии EF Core 5 устранена. Легко заметить, что класс
PersonNULLРешить задачу можно двумя способами. Первый — включить допустимость
nullPersonalInformationnull