2013-12-18 28 views
2

我有一個模型與幾個繼承類。我有一個4級的層次結構:代碼優先EF 6表每個層次SQL查詢生成問題

--First level abstrac class A 
    --Second level abstrac class AA 
    --Third level: 
    *abstract class AAA 
    *abstract class AAB 
    *abstract class AAC 
    *class AAD 
    *class AAE 
    *abstract class AAF 
    *class AAG 
    *class AAH 
    *abstract class AAI 
     --Fourth level: 
     *class AAA1 
     *class AAA2 
     *class AAA3 
     *class AAB1 
     *class AAB2 
     *class AAB3 
     *class AAC1 
     *class AAC2 
      ... 
     *class AAF1 
     *class AAF2 
     *class AAF3 
     *class AAF4 
     *class AAF5 

這只是其中一個層次結構。至少還有3個,不那麼複雜。他們之間有幾個關係,幾乎所有的班級都有超過7個屬性。現在

,我使用的表每種類型的,但是當我做了一個簡單的LINQ查詢,如:

 using (Logic.Context dc = new Logic.Context()) 
     { 
      var prod = dc.AA.FirstOrDefault(); 
     } 

AA包含所有子類。當數據庫爲空時,執行此簡單測試需要大約25秒的時間。只需2秒即可完成與四級課程相同的LINQ查詢。

我試圖遷移到每個層次的表,數據庫默認生成的列Discriminator,但同樣的測試需要永遠... LINQ查詢從未執行,甚至沒有完成。這發生在所有桌子上。

有什麼建議嗎?

回答

0

我的理論是,它採取永遠只是做FirstOrDefault因爲上下文不知道哪一個實體是「第一」

它基本上是問自己:首先AA?獲取實體1 - 這是...(25秒過去)哦,它是AAH!幹得好!

嘗試查詢投影到一個對象,可以從剛剛AA

獲得所有屬性例如,如果AA是

class AA 
{ 
    public Int32 Id {get;set;} 
    public String Name {get;set;} 
    public DateTime Created {get;set;} 
} 

那麼你的查詢可能運行得更快,如果你做

var prod = dc.AA.Select(a => new 
{ 
    Id = a.Id, 
    Name = a.Name, 
    Created = a.Created 
}).FirstOrDefault(); 

然後在理論上,也許EF不會關心第一個實體是什麼。

但是...

雖然我在這裏 - 我只是重構所有的TPT了我,因爲EF的CASE的項目/ JOIN地獄。
我知道用這種SQL繼承來玩這種感覺是對的,可愛的,但是當你不得不看一個AA實例並找出它的真實性時,它可以並且會燒你。

+0

那麼,我剛剛離開了TPH的想法,並與TPT保持着聯繫。爲了避免25秒的等待,我只是避免AA。在我的項目中,我全部用反思來避免表AA,結果很好,但對程序來說有點困難。使用反射,我會在3或4秒內查詢AA的所有項目。 –