2017-04-07 115 views
0

EF 6.1.3。具有組合外鍵的實體框架導航屬性

我有一個包含許多「Header/Item」類型模式的實例的域,其中Header可以包含許多項目(1到多個),並且還包含「當前」或「最新」項目。

Header 
    Guid Id 
    Guid CurrentItemId 
    Item CurrentItem 
    ICollection<Item> AllItems 

Item 
    HeaderId 
    Id 

物品的PK總是HeaderID +的ItemID:

這表示如下。原因是,到目前爲止,項目最常見的訪問模式是列出與給定頭相關的所有項目,並且使HeaderID成爲PK /聚簇索引的第一部分意味着我們獲得具有聚簇索引的數據。

我們的問題是,當我們使用CURRENTITEM導航屬性,它永遠只能使用項目ID做的查找,從而導致沒有那麼大的查詢計劃。

我認爲這是因爲我們使用CurrentItemId查找CurrentItem的約定。我的問題是,有沒有辦法讓我告訴EF總是通過映射Header.Id,Header.CurrentItemId - > Item.HeaderId,Item.Id?來執行它對CurrentItem的連接。

我相信這是比這裏所描述的略有不同的情景:composite key as foreign key

就我而言,我有一個一對一的映射不是一個頂部多了,似乎沒有成爲一個WithforeignKey方法可用於該場景。

+0

[複合鍵作爲外鍵]的可能重複(http://stackoverflow.com/questions/5436731/composite-key-as-foreign-key) – niksofteng

+0

我不確定它是重複的,因爲該帖子您引用的實體之間沒有列不匹配。在我的情況下,除了映射到Item實體中的ID字段的CurrentVersionID字段之外,Header的ID字段還需要映射到Item.HeaderId字段。它也是一對一映射的情況,而不是一對多映射,並且Item實體沒有導航屬性返回到Header。 這可能是一個小小的差異,但它讓我絆倒。 – RMD

+0

我們在一些非常類似的地方工作,但使用整數並且沒有這個問題。我認爲EF可能會以不同的方式處理guid,或者如果它在表上有唯一的約束,它會嘗試使用它。 此外,guid可能會導致碎片問題,我知道我們在SQL Server中遇到了這個問題。 –

回答

0

我們最終沒有能夠得到EF生成SQL我們想要的方式 - 所以我們寫了一個數據庫命令截取動態發現的情況下,這種加入和重寫加入符合我們設計的複合鍵。

我們配置此作爲的DbContext水平,像這樣:

this.ModifyJoin<Item, Header>(
     (i) => new Header() { CurrentItemId = i.Id }, //What to find 
     (i) => new Header() { CurerntItemId = i.Id, Id = i.HeaderId }); //What to replace with 

該信息被附加到上下文實例本身,所以當命令截取看到覆蓋,它使用他們重新編寫SQL。

這對於大多數場景來說結果很好,但也有一些 - 比如當作爲LINQ語句的一部分在Item表上進行附加過濾時,EF使用的別名規則變得太複雜,一個完整的SQL解析器。

對於我們的使用,這導致理想的加入約90%的時間,這對我們來說已經足夠好了。

完成所有這些工作的代碼並不困難,但放在這裏太大了。如果您想要一個副本,請添加評論,然後放在GitHub上。