Язык программирования 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>();
}
По умолчанию два свойства
Person
PersonalInformation_FirstName
PersonalInformation_LastName
OnConfiguring()
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)");
});
});
Вот как будет создаваться результирующая таблица (обратите внимание, что допустимость значений
null
FirstName
LastName
Person
CREATE 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 устранена. Легко заметить, что класс
Person
NULL
Решить задачу можно двумя способами. Первый — включить допустимость
null
PersonalInformation
null