5

考虑以下情况:

我有另外两个继承的基类。例如,我们将有:

class Base
{

}
class DerivedA : Base
{

}
class DerivedB : Base
{

}

当我使用类似代码请求基本实体时

context.Base.Where(q => q.Id == id).First();

实体框架为每个派生实体生成一整套连接,导致查询性能低于可接受的水平。我想要的是仅加载基本实体而不将其加入派生实体。

我在这里找到的唯一解决方案http://blogs.msdn.com/b/alexj/archive/2009/09/17/tip-35-how-to-write-oftypeonly-tentity.aspx。但这对我不起作用。EF 仍然会生成大量查询。

编写查询,例如:

context.Base.Where(q => !(q is DerivedA) && !(q is DerivedB)).First();

由于派生类型的数量不断增加,也不适合我。

除了我提到的之外,还有其他可能的解决方案吗?

4

2 回答 2

5

您正在使用 Table-per-type => EF 必须生成这些连接,因为它不知道您的实体到底是什么类型。如果您的记录在表Base中有相关​​记录,则它不能为该记录创建实体实例-它必须创建实例,并且它需要进行连接以获取此知识。DerivedABaseDerivedA

长时间讨论为什么不允许这样做,而只是实体来自对象世界-它是原子数据结构,可以保存到多个表中,但对对象世界不可见。如果您坚持 a Base,您将加载回 a Base,但如果您坚持DerivedA,您将始终加载回来DerivedA,而不仅仅是Base因为它会破坏实体的原子性。

我没有尝试过,但我认为 ESQLOFTYPE ONLY运算符也应该进行连接,以确保它确实加载了基础实体的真实实例,而不是派生实体的损坏实例。

Table-per-type 会产生缓慢的查询。.NET 4.5 应该改进它,但我认为改进不会针对这些情况 - 我认为它们将OfType针对派生类型和投影。

如果您只需要Base表格中的数据,您最好的选择是:

于 2012-07-19T16:14:22.947 回答
0

您可以引入一个没有进一步含义/功能的抽象中间类,所有派生类型都必须从中派生:

class Base
{

}
abstract class DerivedBase : Base
{

}
class DerivedA : DerivedBase 
{

}
class DerivedB : DerivedBase 
{

}

然后你可以做一个简单的查询,不管有多少派生类存在:

context.Bases
  .Where(b => !(b is DerivedBase))
  ...
于 2015-09-29T15:08:32.593 回答