簡體   English   中英

實體框架6大查詢繼承

[英]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 ,和兩種特定的PersonsTeachersStudents 有兩種流行的實現繼承的策略

每種類型的表格(TPT)

每個類都在單獨的表中表示。 在我們的例子中創建了三個表:一個Persons表, Teachers與外國鍵表Person是和Students表的外鍵的Person的數據Student

如果您查詢:“給我……的Persons ”,則只需要檢查一張桌子。 但是,如果您問:“給我...的Students ”,則需要“ Persons表和“ Students表之間的Persons

如果添加/更新/刪除一個Student ,則需要更新兩個表。

如果將來需要將一列添加到其中一個類中,則僅涉及一個表。

添加一個新的Person ,例如Sponsors很容易,但是它們必須是Persons並繼承所有Person列。 如果以后您確定Sponsor不再是Person ,那么您將遇到麻煩。

如果您對Persons詢問要比對StudentsTeachers詢問要多得多,則此方法最合適。 如果您經常詢問Students with Person data則不太適合。 另外,如果您經常添加/刪除/更新Students ,請不要使用此方法。

如果你需要創建一個同樣使用此方法Person既不是Teacher ,也不是Student還沒有,但以后可能會成為他們中的一個,也許兩個TeacherStudent

每個創建類(TPC)的表

沒有用於Persons單獨表。 所有“ Person屬性都在“ Teachers表和“ Students表中。

查詢“ ...的學生”或“ ...的老師”將僅涉及一個表。 但是,查詢“ Persons that ...”將涉及從“ Students表中檢索的數據與從“ Teachers表中檢索的數據的串聯。

添加/刪除/更新Student將始終涉及一個表。

Student添加一列涉及更改一個表。 但是,向“ Person添加列涉及更改“ Students和“ Teachers表。

添加新的Person ,例如JanitorsSponsors很容易。 如果將來的Sponsor不再是Person ,這將不是問題。

您不能創建Person ,它總是必須是TeacherStudent 一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM