[英]Entity Framework 6 big query in inheritance
我有一個繼承策略“每種類型的表(TPT)”,其中的抽象類“ Task”具有很多具體類(例如30個類)。 當我嘗試顯示“要做任務”的工作清單時,向EF詢問抽象類,或者當我嘗試通過ID獲得通用任務時,EF會進行10000行查詢來加入每個具體的類,結果非常慢。 有沒有一種方法可以配置EF以避免大查詢? 在工作清單方法中,我只需要抽象類的字段。
這是我的代碼:
public Task GetTaskById(int id) {
return this.repository.Tasks.Where(t => t.ID == id).FirstOrDefault();
}
public IQueryable<Task> GetWorklist() {
return this.repository.Tasks.Where(t => a.ActivitySate.Code == ActivitySateEnum.TO_DO);
}
謝謝
問題是您使用的ba存儲庫不返回IQueryable,因此它不允許EF實際使用您擁有的過濾器(您確實對嗎?),其中將返回的數據限制為僅某些字段。
因此,讓實體化的是實體(這是存儲庫反模式的SOOOO標准)。 然后您就可以了....為此...需要加入TPT。 那是30個類,這意味着30多個表。 首先,查詢可能沒有1萬行。 其次,對於真正復雜的SQL(您在此處擁有)來說,這是正常且很小的。 第三,您自己設置-是的,這是提取所有數據所需要的。
解? 擺脫suplus信息庫(您知道DbContext是一個信息庫),然后根據基本類型進行過濾,並確保僅將所需字段投影到匿名類中,以便EF可以進行優化。
關系數據庫不能很好地處理繼承的概念。 為實體框架模擬繼承發明了幾種策略。
哪種策略最適合您,取決於您最常執行哪種查詢和更新。
假設您有一個班級Person
,和兩種特定的Persons
: Teachers
和Students
。 有兩種流行的實現繼承的策略
每個類都在單獨的表中表示。 在我們的例子中創建了三個表:一個Persons
表, Teachers
與外國鍵表Person
是和Students
表的外鍵的Person
的數據Student
。
如果您查詢:“給我……的Persons
”,則只需要檢查一張桌子。 但是,如果您問:“給我...的Students
”,則需要“ Persons
表和“ Students
表之間的Persons
。
如果添加/更新/刪除一個Student
,則需要更新兩個表。
如果將來需要將一列添加到其中一個類中,則僅涉及一個表。
添加一個新的Person
,例如Sponsors
很容易,但是它們必須是Persons
並繼承所有Person
列。 如果以后您確定Sponsor
不再是Person
,那么您將遇到麻煩。
如果您對Persons
詢問要比對Students
和Teachers
詢問要多得多,則此方法最合適。 如果您經常詢問Students with Person data
則不太適合。 另外,如果您經常添加/刪除/更新Students
,請不要使用此方法。
如果你需要創建一個同樣使用此方法Person
既不是Teacher
,也不是Student
還沒有,但以后可能會成為他們中的一個,也許兩個Teacher
和Student
沒有用於Persons
單獨表。 所有“ Person
屬性都在“ Teachers
表和“ Students
表中。
查詢“ ...的學生”或“ ...的老師”將僅涉及一個表。 但是,查詢“ Persons that ...”將涉及從“ Students
表中檢索的數據與從“ Teachers
表中檢索的數據的串聯。
添加/刪除/更新Student
將始終涉及一個表。
向Student
添加一列涉及更改一個表。 但是,向“ Person
添加列涉及更改“ Students
和“ Teachers
表。
添加新的Person
,例如Janitors
或Sponsors
很容易。 如果將來的Sponsor
不再是Person
,這將不是問題。
您不能創建Person
,它總是必須是Teacher
或Student
。 一個Student
永遠不能成為一個Teacher
,他將成為一個新的Person
(這似乎有點諷刺意味:-)。 沒有Student
也可以當Teacher
。
如果您很少詢問Persons who ...
,但最經常詢問Students who ...
請使用此方法
選擇繼承的策略取決於您如何使用表。
您似乎已將30種Persons
實現為TPC(沒有單獨的Persons
表)。 如果你問的Persons who
......,你的數據庫有來連接所有30桌的結果。
如果您認為這是迄今為止最常用的查詢,請考慮將繼承策略更改為TPT。 是否應該這樣做取決於數據庫是否已經填充了很多數據。 如果使用代碼優先,則可能會從一個相當空的數據庫開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.