我知道這個問題上有很多問題,但我沒有設法找到一個實際解釋如何解決我的問題特別的問題。我想這意味着它可能不可能解決(我認爲這可能是EF的思維方式「倒退」),但我必須問。用Code First定義實體框架中的一對一或零關係
我有三個(略)波蘇斯模型像這樣:
[Table("People")]
public class Person {
public int PersonID { get; set; }
[Required]
public string PersonName { get; set; }
}
public class Location {
public int LocationID { get; set; }
public int LocationTypeID { get; set; }
public virtual LocationType LocationType { get; set; }
}
public class Van : Location {
public int PartyID { get; set; }
public virtual Party Party { get; set; }
}
這些由(略)數據庫表支持(我們寫這些手工):
CREATE TABLE People (
PersonID INTEGER IDENTITY NOT NULL,
PersonName VARCHAR(255) NOT NULL,
PRIMARY KEY (PersonID)
)
CREATE TABLE Locations (
LocationID INTEGER IDENTITY NOT NULL,
LocationTypeID INTEGER NOT NULL,
FOREIGN KEY (LocationTypeID) REFERENCES LocationTypes(LocationTypeID)
)
CREATE TABLE Vans (
LocationID INTEGER NOT NULL,
PersonID INTEGER NOT NULL,
PRIMARY KEY (LocationID),
FOREIGN KEY (LocationID) REFERENCES Locations(LocationID),
FOREIGN KEY (PersonID) REFERENCES People(PersonID)
)
你可以大概想象一下LocationTypes
的樣子。
Locations
是每個表類型的層次結構的根目錄 - 也有檢查約束來執行此操作。 Vans
是一種位置,因爲其他東西無關像Warehouse
。現在
,一個Van
屬於Person
,在我們發出了一輛麪包車到員工,它是他們的責任與燃料填滿它,不會崩潰,它需要客戶的網站時,他們已經爲了更多的東西用完了所有的螺絲,鑽頭和鎧裝直流電纜。然而,並非每個Person
都有一輛貨車(其中一些在一輛貨車中成對運行),而Person
表沒有指向Van
的外鍵 - 反過來也是如此。這在某種意義上是歷史事故,但它對整個情況非常整潔地模擬,因爲雖然Person
不必具有Van
,但最確定地必須有一個人。
所以對我的問題:我如何得到Person
導航屬性與他們的Van
它?
public virtual Van Van { get; set; }
我所做的與數據註釋和流暢的API玩弄了很多,我已經得到了最接近的是這OnModelCreating
:
modelBuilder.Entity<Van>()
.HasRequired(v => v.Person)
.WithOptional(p => p.Van);
可惜這試圖填充Van
屬性與代理產生一個Location
對象。它甚至可能是正確的Location
對象(我無法檢查),但它沒有意識到它應該在尋找貨車。然而,我懷疑它可能試圖匹配PersonID
與LocationID
,當它進行查找時 - 沒有Fluent API映射,我根本沒有任何麪包車,這是我所期望的(所有PersonID
值都低於與貨車對應的最低LocationID
值,所以無法找到任何東西)。
這無疑將是很容易的,如果Person
有一個空的外鍵Van
,但後來我們不得不在兩個方向上的外鍵,如果我們拿了一個出來的Van
那麼我們就無法建模絕對必要的約束,即Van
有一個Person
。
所以,我認爲,Van
擁有這種關係,並Van
財產上Person
是逆導航屬性,但它似乎EF是不是在這個把戲的一個對的人,即使一端非常好是可選的。有沒有辦法讓它工作,還是我必須接受妥協?
爲了實體框架的缺失特性,我們通常拒絕妥協數據庫模型。我真正需要的是一種告訴EF的方式,Person
上的Van
屬性可以通過加入Vans上的Vans on Vans.PersonID = Person.PersonID來填充。
我希望情況並非如此,但這是我最終發佈後實施的解決方案這個問題只是讓我們能夠得到它的工作。至少數據庫知道發生了什麼! –