簡體   English   中英

EF Core 2.2中的不同類一對一

[英]One-to-one with different classes in EF Core 2.2

我想關注這個博客,解釋如何配置一對一關系。 它的想法是,一個實體獲得另一個類型的屬性,而另一個獲得前者類型的屬性以及為其創建外鍵的ID。

但我的問題是,我想像這樣制動兩個不同類的接觸部分。 SomeThing類已經被重構,並且可以與Address一起很好地工作。 但是,我不確定如何處理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並且完全跳過了Address 但是我記得從前,繼承和EF混合得不好,並且在這種情況下會有很多麻煩和麻煩。

有可靠的最佳做法嗎? 當我用Google搜索時,沒有發現任何可以信賴的東西。

從評論中的討論中,我將進入一個詳細的答案:

您可以使用EF Core新引入的擁有實體類型功能,其中AddressSomethingSomethingElseOwned Entity類型,而SomethingSomethingElse是擁有者,如下所示:

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

按照約定,EF Core將按照Navigation_OwnedEntityProperty模式為擁有實體類型的屬性命名數據庫列。 因此,“ Address屬性將顯示在SomethingSomethingElse表中,名稱為“ 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>
  • 您不能在ModelBuilder上使用擁有類型調用Entity<T>()

有關更多詳細信息: EF核心擁有的實體類型限制

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM