Индивидуальные занятия с разными классами в EF Core 2.2 - PullRequest
0 голосов
/ 02 февраля 2019

Я хотел бы подписаться на этот блог , объясняющий, как настроить отношения один-к-одному.Его идея состоит в том, что одна сущность получает свойство типа другого, а другая получает свойство типа первого плюс идентификатор для него, чтобы создать внешний ключ.

Однако моя проблема в том, что я хочутак тормозить контактную часть двух разных классов.Класс SomeThing уже переработан и хорошо работает с классом Адрес .Однако я не уверен, что делать с классом SomeThingElse .

public class SomeThing
{
  public Guid Id { get; set; }
  //public string Street { get; set; }
  //public string City { get; set; }
  public Address Address { get; set; }
}

public class Address
{
  public Guid Id { get; set; }
  public string Street { get; set; }
  public string City { get; set; }
  public Guid SomeThingId { get; set; }
  public SomeThing SomeThing { get; set; }  
}

public class SomeThingElse
{
  public Guid Id { get; set; }
  public string Street { get; set; }
  public string City { get; set; }
  //public Address Address { get; set; }
}

Я пытался добавить специализированный класс для управления адресом SomeThingElse но тогда не имеет смысла разбивать это.Я рассмотрел добавление двух полей ниже, но отклонил эту идею как плохой дизайн для БД.

public class Address
{
  ...
  public Guid SomeThingElseId { get; set; }
  public SomeThingElse SomeThingElse { get; set; }  
}

Предпочтительно, это школьная книга для наследования, представляющая базовый класс Contactable и пропускающая Адрес в целом.Но я помню, что ранее наследование и EF не смешивались хорошо, и что в этом случае можно ожидать много опций и ошибок.

Есть ли надежная лучшая практика для этого?Я не нашел ничего, что казалось бы достаточно надежным, когда я гуглил.

1 Ответ

0 голосов
/ 03 февраля 2019

Начиная с обсуждения в комментариях, я перейду к подробному ответу:

Вы можете использовать EF Core недавно представленный Owned Entity функция типа где Address - это Owned Entity тип Something и SomethingElse, тогда как Something и SomethingElse являются владельцами следующим образом:

modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address);
modelBuilder.Entity<SomeThingElse>().OwnsOne(st => st.Address);

По соглашению EF Core будет называть столбцы базы данных длясвойства принадлежащего типа сущности по шаблону Navigation_OwnedEntityProperty .Поэтому свойства Address появятся в таблице Something и SomethingElse с именами 'Address_Street' и 'Address_City'.

Теперь, если вы не хотите, чтобы имя столбца с собственным типом сущности было похоже Navigation_OwnedEntityProperty затем вы можете задать имя своего пользовательского столбца следующим образом:

modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address,
     a =>
     {
          a.Property(p => p.Street).HasColumnName("Street");
          a.Property(p => p.City).HasColumnName("City");
     });

modelBuilder.Entity<SomeThingElse>().OwnsOne(ste => ste.Address,
     a =>
     {
          a.Property(p => p.Street).HasColumnName("Street");
          a.Property(p => p.City).HasColumnName("City");
     });

Кроме того, собственные типы могут храниться в отдельной таблице от владельца.Чтобы переопределить соглашение, согласно которому принадлежащий тип сопоставляется с той же таблицей, что и владелец, вы можете просто вызвать ToTable и указать другое имя таблицы следующим образом:

modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address,
      a =>
      {
            a.ToTable("SomeThingAddress");
      });

 modelBuilder.Entity<SomeThingElse>().OwnsOne(ste => ste.Address,
      a =>
      {
          a.ToTable("SomeThingElseAddress");
      });

Запрос собственных типов

При запросе владельца по умолчанию будут включены принадлежащие ему типы.Нет необходимости использовать метод Include, даже если принадлежащие типы хранятся в отдельной таблице.

Ограничения

Некоторые из этих ограничений являются основополагающими для работы типов собственных сущностей, но некоторыедругие ограничения, которые мы сможем снять в будущих выпусках:

Ограничения на уровне конструкции:

  • Вы не можете создать DbSet<T> для собственного типа
  • Вы не можете позвонить Entity<T>() с собственным типом на ModelBuilder

Для более подробной информации: Ограничения на типы, принадлежащие базовому объекту EF

...