代码优先EF 6表每层次SQL查询生成问题

时间:2013-12-18 14:10:41

标签: c# linq entity-framework code-first table-per-hierarchy

我有一个带有继承的几个类的模型。我有一个4级层次结构:

--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秒。使用第四级类执行相同的LINQ查询仅需2秒。

我尝试迁移到每个层次结构表,默认情况下使用列Discriminator生成数据库,但同样的测试需要永远... LINQ查询永远不会执行,甚至都没有完成。这种情况发生在所有表格中。

有什么建议吗?

1 个答案:

答案 0 :(得分: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可能不关心第一个实体究竟是什么。

<强>可是..

我在这里 - 由于EF的CASE / JOIN地狱,我刚刚从我的项目中重构了所有TPT 我知道使用像这样的SQL继承感觉是正确和可爱的,但是当你必须查看AA实例并找出它实际上是什么时它会烧掉你。