2011-05-10 311 views
1

使用EF 4.0和POCO的4.1升級/代碼優先。如何在不使用HasForeignKey的情況下引用外鍵()

好吧,所以我有一個域模型,其中Car類型在一個集合中有Part類型的多個對象。所以一個:很多關係。

HasMany(v => v.Parts) 
    .WithRequired() 
    .HasForeignKey(v => v.CarId) 
    .WillCascadeOnDelete(); 

這裏的問題是,它需要我去CarId屬性添加到我的Part類型。這是將ORM細節泄漏到我的域模型中 - 這很糟糕。標記虛擬內容已經夠煩人的了。

看着爲HasForeignKey()方法的XML文檔註釋這樣說:

配置使用的是 對象模型暴露 外鍵屬性(一個或多個)的關係。 如果 外鍵屬性不是 暴露在對象模型中,則使用 的Map方法。

這是偉大的,所有。但它引入了一個catch-22的情況,因爲如果我通過刪除CarId屬性來重構我的Part類型,我不想要並更新我的EF模型構建器以便不打擾映射該屬性。然後,你可以想像這意味着我不能再調用HasKey()定義組合鍵,鼻翼:

HasKey(v => new { v.CarId, v.PartId }); 

HasKey()似乎並不支持定義一種基於非財產lambda表達式的關鍵。

這裏有什麼解決方案?

+0

我認爲你的問題標題應該是:「如何定義一個主鍵,而不必將所有主鍵列暴露爲模型中的屬性?」這不是問題嗎?通過殺死「CarId」,你不僅要移除FK屬性(這很容易),而且也是你複雜PK的一部分(這可能是不可能的)。 – Slauma 2011-05-10 15:06:55

+0

你是對的。這裏的關鍵是我不想在我的領域模型中使用多餘的「後向引用」。領域模型不需要他們,他們只是一個痛苦,保持同步。我很驚訝EF似乎需要用反向引用來污染我的領域模型 - 這純粹是一個RDBMS問題。 – nbevans 2011-05-12 11:45:05

+0

您不需要在EF中返回引用,它是可選的。你的問題是你有一個複合主鍵,並且它的一部分是一個外鍵。通常情況下,你可以擺脫外鍵屬性,但不是在你的情況下,因爲它是同時PK的一部分。而且你不能從模型類中刪除PK。你最好的選擇是將'PartId'作爲主鍵,然後你可以刪除'CarId'。這基本上是hazimdikenli在他的回答中提出的。 – Slauma 2011-05-12 12:44:34

回答

1

如果您絕對不希望在模型中使用外鍵屬性,則可以移除約定以檢測FK屬性,以避免EF自動將屬性標記爲FK屬性...

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Conventions 
     .Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>(); 
} 

...然後乾脆不指定在映射的FK屬性:在你的模型

HasMany(v => v.Parts) 
    .WithRequired() 
    .WillCascadeOnDelete(); 

你仍然需要CarId,因爲它是主要的一部分關鍵,但這樣它就不會起作用作爲外國關鍵財產。

只是一個想法,我不知道它是否工作。

1

那麼,怎麼樣像CarPartId添加一個新的關鍵字到CarParts表,所以你不需要組合鍵。 (使用ORM時複合鍵支持並不是那麼好)

相關問題