[英]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新引入的擁有實體類型功能,其中Address
是Something
和SomethingElse
的Owned Entity
類型,而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>
ModelBuilder
上使用擁有類型調用Entity<T>()
有關更多詳細信息: EF核心擁有的實體類型限制
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.