我更新了標題以使其更具相關性。
我有兩個物件,并希望使用 EF Core 首先使用代碼將它們映射到資料庫。
為了簡潔起見,我將它們縮短了一點。
WeddingDetails
{
VenueDetails ReceptionDetails { get; set; }
VenueDeails WeddingDetails { get; set; }
}
VenueDetails
{
string StreetAddress { get; set; }
string PostCode { get; set; }
public int WeddingDetailsId { get; private set; }
public WeddingDetails WeddingDetails { get; private set; }
}
但是,在嘗試進行初始遷移時,我從 Entity Framework Core 收到以下錯誤:
無法確定由“VenueDetails”型別的導航“WeddingDetails.ReceptionDetails”表示的關系。手動配置關系,或使用“[NotMapped]”屬性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此屬性。
問題是receptiondetails 和weddingdetails 都是同一個物件,我相信,當Entity Framework Core 嘗試將其轉換為遷移時,這會導致沖突。
誰能幫我理解我必須OnModelCreating使用 Fluent API 添加到方法中的配置選項/我需要對物件進行更改以消除這種沖突,謝謝。
編輯
我實際上通過創建一個父類來解決這個問題,該父類從接收和婚禮派生,然后物體框架能夠區分這兩個物件并使用鑒別器將它們保存在表中。
所以我像下面一樣更新了它
VenueDetails
{
string StreetAddress { get; set; }
string PostCode { get; set; }
}
WeddingVenueDetails : VenueDetails
{
}
ReceptionVenueDetails : VenueDetails
{
}
然后 EF 能夠決議這個。我給史蒂夫的答案,而不是我自己回答的原因是,這不是我決定采用的方法,而是他建議的更多,實際上將兩個類分解為它們自己的物件以允許未來的靈活性和解耦
uj5u.com熱心網友回復:
就關系中 FK 的位置而言,這里的關系有點倒退。一對一關系通常由雙方的 PK 關聯,但是可以將 EF 配置為使用一對多資料庫端關系(右側表上的 FK)或多對一的資料庫端關系(左側表上的 FK)
例如,給定您的預期結構 /w Wedding 和 Venues,您希望單個 Wedding 指向一個 WeddingVenue 和一個 ReceptionVenue。下一個問題是 FK 應該駐留在哪里。對于WeddingVenue,您已將其設定為與Venue 表中的WeddingID 的一對多FK。然而,這使得資料庫將如何計算 ReceptionVenue 的 FK 的問題懸而未決。
您可以通過交換到多對一 FK 來解決此問題,其中 WeddingVenueId 和 ReceptionVenueId 是婚禮表/物體的一部分。如果我們在物體中公開 FK 屬性作為示例:
public class WeddingDetails
{
[Key]
public int WeddingDetailsId { get; set; }
// ... wedding fields...
public int WeddingVenueId { get; set; }
public int ReceptionVenueId { get; set; }
[ForeignKey("WeddingVenueId")]
public virtual VenueDetails WeddingVenueDetails { get; set; }
[ForeignKey("ReceptionVenueId")]
public virtual VenueDetails ReceptionVenueDetails { get; set; }
}
現在,這在技術上建立了兩個多對一關系,其中模型配置如下所示:
modelBuilder.Entity<WeddingDetails>()
.HasOne(x => x.WeddingVenueDetails)
.WithMany();
但是,我們希望在 VenueDetails 上有一個 WeddingDetails 實體。還有一個考慮因素是 ReceptionVenueDetails 是一個 VenueDetails,該場所不會有一個 WeddingDetails 參考,因此將這種關系保留為多對一可能是有意義的。
這里的問題是沒有什么可以阻止相同的場地記錄:
- 用于婚禮場地和接待場地。
- 被用作完全不同的婚禮的婚禮和/或接待場所。
這意味著,如果兩場婚禮與同一場地記錄相關聯,則一場婚禮場地的更新將反映在與同一記錄相關聯的任何其他婚禮上。即使我們將 EF 配置為期望它們是一對一的關系(我們可以使用 EF Core 5/6 using HasPrincipalKey),事實是資料庫 FK 約束將始終允許兩個婚禮參考相同的 Venue 記錄. 這形成了一種虛假的一對一關系。
將其強制為正確的一對一的方法是將場地詳細資訊(用于婚禮和招待會)嵌入到婚禮表中(作為 EF Core 中的同表擁有型別),或者建立一個WeddingVenueDetails作為一對一的關系表。(使用標準的一對一 PK 關系或單獨的表擁有型別)
從物體看這會是什么樣子:
public class WeddingDetails
{
[Key]
public int WeddingDetailsId { get; set; }
// ... wedding fields...
public virtual WeddingVenueDetails WeddingVenueDetails { get; set; }
}
public class WeddingVenueDetails
{
[Key]
public int WeddingDetailsId { get; set; }
string WeddingStreetAddress { get; set; }
string WeddingPostCode { get; set; }
string ReceptionStreetAddress { get; set; }
string ReceptionPostCode { get; set; }
public virtual WeddingDetails WeddingDetails { get; set; }
}
在這里,WeddingVenueDetails 負責單個特定婚禮的婚禮和接待地點的詳細資訊。我們可以在兩者之間建立適當的一對一關系:
modelBuilder.Entity<WeddingDetails>()
.HasOne(x => x.WeddingVenueDetails) // or OwnsOne()
.WithOne(x => x.WeddingDetails);
在資料庫表中,WeddingDetailsId 充當兩個表和 FK 約束之間的唯一 PK。這實作了純粹的一對一關系,其中任何婚禮的場地細節都可以安全地編輯,而不會影響任何其他婚禮的場地。
同樣,如果您想將WeddingVenue 和ReceptionVenue 分開,您可以這樣做,但是每個人都需要自己的單獨表,并使用WeddingDetailsID 作為PK 并使用相同的HasOne/WithOne. (WeddingVenueDetails 和 ReceptionVenueDetails 表)它們不能是相同的 VenueDetails 表/物體,以強制與 WeddingDetails 建立純粹的一對一關系。(不存在一對二或一對零或二的關系。)這似乎并不理想,因為這兩個表將有效地共享相同的列,但從存盤 POV 來看,它本質上是無論 2 條記錄存盤在 1 個表中,還是 1 條記錄存盤在兩個表中,都是相同的。它還適應未來的靈活性,您可能擁有僅適用于婚禮或招待會的場所欄位,這些欄位可以添加到相應的表中,而無需借助條件可空列。在最壞的情況下,您最終不得不求助于一個或另一個隱含需要的可空列,而在資料庫中實際上沒有強制執行該列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/469407.html
上一篇:物體框架中的連接字串
下一篇:使指標指向char陣列的元素?
