public Person PersonalInformation { get; set; } = new Person;

  [JsonIgnore]

  [InverseProperty(nameof(CreditRisk.CustomerNavigation))]

  public IEnumerable CreditRisks { get; set; } =

    new List;

  [JsonIgnore]

  [InverseProperty(nameof(Order.CustomerNavigation))]

  public IEnumerable Orders { get; set; } = new List;

}

По умолчанию два свойства Person отображаются на столбцы с именами PersonalInformation_FirstName и PersonalInformation_LastName. Чтобы изменить это, добавьте в метод OnConfiguring следующий код Fluent API:

modelBuilder.Entity(entity =>

{

  entity.OwnsOne(o => o.PersonalInformation,

      pd =>

      {

   pd.Property(nameof(Person.FirstName))

             .HasColumnName(nameof(Person.FirstName))

             .HasColumnType("nvarchar(50)");

        pd.Property(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 содержит аннотации данных Required для обоих своих свойств, но оба столбца SQL Server определены как допускающие NULL.Так происходит из-за проблемы с тем, каким образом система миграции транслирует принадлежащие сущности, когда они используются с необязательным отношением. Для исправления проблемы потребуется сделать отношение обязательным.

Решить задачу можно двумя способами. Первый — включить допустимость null на уровне проекта или в классах С#. Тогда навигационное свойство PersonalInformation становится не допускающим значение null, что исполняющая среда EF Core учитывает и соответствующим образом конфигурирует столбцы в принадлежащей сущности. Второй способ предусматривает добавление кода Fluent API для того, чтобы сделать навигационное свойство обязательным:

modelBuilder.Entity(entity =>

{

  entity.OwnsOne(o => o.PersonalInformation,

      pd =>

      {

        pd.Property(nameof(Person.FirstName))

             .HasColumnName(nameof(Person.FirstName))

             .HasColumnType("nvarchar(50)");

        pd.Property(nameof(Person.LastName))

             .HasColumnName(nameof(Person.LastName))

             .HasColumnType("nvarchar(50)");

      });

  entity.Navigation(c => c.PersonalInformation).IsRequired(true);

});

Существуют дополнительные аспекты для исследования с помощью принадлежащих сущностей, в том числе коллекции, разбиение таблиц и вложение, но они выходят за рамки тематики настоящей книги. За более подробной информацией о принадлежащих сущностях обращайтесь в документацию по EF Core: https://docs.microsoft.com/ru-ru/ef/core/modeling/owned-entities.

<p id="AutBody_Root939"><strong>Сопоставление с функциями базы данных</strong></p>
Перейти на страницу:

Похожие книги