好了,一個一對多的關係被稱爲一個一對多因爲在關係的第一端與許多因素有關一個元素另一端。您也可以有一個零或一個對多關係,這隻意味着非多方的元素可以是null
(或數據庫中的NULL
)。
你正在嘗試定義是一對多(或者零個或一個或兩個一對多)的關係。這樣的事情不存在於關係數據庫中,也不存在於實體框架中。
當您定義與EF的關係時,您總是需要對的源和目標類中的兩個導航屬性。它是可能省略一個的導航屬性,但這並不意味着您可以將此關係的末尾移動到另一個已屬於另一個關係的導航屬性。
在你的具體情況下,你有兩個關係,因爲你的兩個導航屬性FirstEnd
和SecondEnd
在Shaft
代表兩個不同的外鍵。因此,您需要Coupling
中的兩個集合,或者您可以將現有的屬性Coupling.Shafts
與FirstEnd
或SecondEnd
關聯,但不能同時關聯到這兩個集合。另一個參考文獻是指Coupling
中的「不可見」未公開導航集合。 (這是在您自己的答案中映射時會發生的情況:EF將採用第二個映射塊來覆蓋第一個映射塊,創建SecondEnd
和Shafts
之間的關係,然後FirstEnd
和未公開關係之間的另一個關係在Coupling
,不Shafts
再次)
有兩個集合的解決方案 - 這使得更多的意義在我看來 - 是這樣的:
public class Coupling
{
public int Id { get; set; }
public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
}
而且這種映射:
modelBuilder.Entity<Coupling>()
.HasMany(x => x.ShaftsWithFirstEndHere)
.WithOptional(x => x.FirstEnd);
modelBuilder.Entity<Coupling>()
.HasMany(x => x.ShaftsWithSecondEndHere)
.WithOptional(x => x.SecondEnd);
您可以創建一個只讀的,沒有映射助手屬性,以連接兩個集合togother一個集合,但已經被加載了兩個導航集合後連接將在內存中發生:
public class Coupling
{
public int Id { get; set; }
public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
// not mapped to DB because it has only a getter = readonly
public IEnumerable<Shaft> Shafts
{
get { return ShaftsWithFirstEndHere.Concat(ShaftsWithSecondEndHere); }
}
}
有沒有一種映射會自動進行這樣的級聯。請注意,一對多關係中的導航集合屬性僅僅是從屬表中的外鍵查詢的結果(在您的示例中爲= Shaft
)。用於填充集合的外鍵(例如使用Include
或者當觸發延遲加載時)通過關係映射很好地定義,並且它只有一個鍵 - FirstEnd
的鍵或SecondEnd
的鍵,但不是兩個鍵。你試圖實現的是由兩個不同的外鍵對兩個查詢的組合級聯結果。這對於關係映射來說是不可能的。
我在ef世界仍然很新鮮。它顯示嗎?感謝您爲我澄清這一點。我的解決方案給了我數據庫中的預期行爲,但是一旦我嘗試使用EF,我遇到了一個很大的錯誤。我會刪除它,因爲我不希望它不小心將其他新手誤導入歧途。 – 2012-07-10 06:41:45