我相信這是一個原因,儘管我可能看不到完整的畫面,可能只是猜測。
情況
事實上,唯一的方法(我見)EF能夠通過只讀取僅列出非高級開發人員(您的查詢用例)的TPT方案爲Developer
表將使用鑑別器,並且我們知道EF不使用TPT/TPC策略中的一個。
爲什麼?那麼請記住,所有高級開發人員都是開發人員,因此他們只有一個Developer
記錄以及一個SeniorDeveloper
記錄是很自然的(也是必要的)。
唯一的例外是,如果Developer
是抽象類型,在這種情況下,您可以使用TPC策略來刪除Developer
表。然而在你的情況下,Developer
是具體的。
目前的解決方案
記住這一點,並沒有在Developer
表鑑別,只有這樣,才能確定是否有任何開發商是一個非高級開發人員是通過檢查,如果它是不一高級開發者;換句話說,通過驗證在SeniorDeveloper
表或任何其他子類型表中沒有開發人員的記錄。
這聽起來有點明顯,但現在我們明白了爲什麼當它的基本類型(開發人員)具體(非抽象)時,必須使用和訪問SeniorDeveloper表。
當前實現
我從記憶寫這個,所以我希望這不是太掉,而這也是什麼Slauma在另一則留言中提到。你可能想要啓動一個SQL分析器並驗證它。
它的實施方式是通過請求表的預測的聯合。這些投影只是添加一個鑑別器,以某種編碼方式聲明他們自己的類型[1]。在聯合集合中,行可以根據這個鑑別器進行過濾。
[1]如果我沒有記錯,它就像這樣:0X爲基本類型,0X0X爲聯合中的第一個子類型,0X1X爲第二個子類型,依此類推。
權衡#1
我們已經可以識別一個權衡:EF可以存儲鑑別表中,或在「運行時」可以「產生一個」。
- 存儲的鑑別器的缺點是它的空間利用率較低,並且可能「醜陋」(如果這是一個參數)。優點是查詢性能在一個非常特殊的情況下(我們只想要基地類型的記錄)。
- 「運行時間」鑑別器的缺點是查找性能不如同樣的用例。優點是它更節省空間。
乍一看,似乎有時我們可能更願意爲查詢性能交易一點點空間,而EF不會讓我們這樣做。
實際上,它並不總是清楚什麼時候;通過請求兩個表的UNION,我們只查找兩個索引而不是一個索引,性能差異可以忽略不計。使用單一級別的繼承,它不會比2倍差(因爲所有子類型集合都是不相交的)。但是,等等,還有更多。
權衡#2
請記住,我說的是存儲,鑑別方法的性能優勢將只出現在特定的使用情況,我們查找的基本類型的記錄。這是爲什麼?那麼,如果你正在尋找可能是或可能不是高級開發者[2]的開發者,那麼你不得不查找SeniorDeveloper
表。雖然這一點看起來很明顯,但可能不那麼明顯的是,EF無法預先知道這些類型是否只屬於某種類型。這意味着在最壞的情況下,它必須發出兩個查詢:Developer
表中有一個,如果結果集中有一個高級開發人員,則在SeniorDeveloper
表中有第二個。
不幸的是,額外的往返可能具有比兩個表的工會更大性能的影響。 (我可能說,我沒有驗證它。)更糟糕的是,它增加了每個在結果集中有一行的子類型。想象一下有3種,5種甚至10種亞型的類型。
這就是你的權衡#2。
[2]請記住,這種操作可能來自應用程序的任何部分,而解決折衷必須在全局範圍內完成以滿足所有進程/應用程序/用戶。此外夫婦,與事實EF團隊必須做出這些權衡所有的EF用戶(雖然這是事實,他們可以添加一些配置爲這些類型的取捨)。
另一種可能
通過批量SQL查詢,將有可能避免多次往返。 EF將不得不向服務器發送一些過程邏輯以進行條件查找(T-SQL)。但由於我們已經建立在權衡#1的性能優勢是最有可能可以忽略不計在許多情況下,我不知道這將永遠是值得的。也許有人可以爲此打開問題單以確定它是否有意義。
結論
在未來,也許有人可以與一些有創意的解決方案,這種特定情況下優化了幾個典型的操作,然後提供一些配置交換機時,優化涉及這樣的取捨。
眼下不過,我認爲EF已經選擇了一個公平的解決方案。以一種奇怪的方式,它幾乎更乾淨。
的幾個注意事項
我認爲使用工會的是在某些情況下應用的優化。在其他情況下,它將是一個外連接,但使用鑑別符(和其他所有內容)保持不變。
你提到的多重繼承,這有點糊塗了最初。在通用的面向對象的說法中,多繼承是一種類型有多種基類型的構造。許多面向對象的類型系統不支持它,包括CTS(由所有.NET語言使用)。你的意思是在這裏。
您也提到,EF將「回退」到TPT策略。在Developer/SeniorDeveloper的情況下,TPC策略與TPT策略的結果相同,因爲Developer是具體的。如果你真的想要一個表,你必須使用TPH策略。
這兩個問題是不相關的。你確定數據真的在'Developers' table =你確定你已經正確配置了TPC嗎? 'OfType'的問題與TPC/TPT無關。這就是'OfType'的工作原理。 – 2012-02-23 10:11:33
OfType確實在tpt ... 中的工作方式,我將每手的值插入到數據庫(開發人員開發人員和高級開發人員僅限高級開發人員),OfType()只給我開發人員,沒有高級開發人員聽起來有點奇怪。 我設置了所有像這裏所說的http://cockneycoder.wordpress.com/2010/11/25/entity-framework-and-concrete-table-per-type-inheritance/ –
relascope
2012-02-24 10:31:43