每种类型性能的实体框架表

Tr1*_*tan 6 inheritance entity-framework table-per-type .net-3.5

事实证明,在实现TPT(每种类型的表)继承时,我是发现微软实体框架中存在的基础底层的最后一个人.

构建了一个包含3个子类的原型,包含20多列的基表/类和包含~10列的子表,一切都运行得很漂亮,我继续研究其他应用程序,证明了这个概念.现在是添加其他20个子类型和OMG的时候了,我刚刚开始查看在简单选择上生成的SQL,即使我只对访问基类上的字段感兴趣.

此页面有一个很好的问题描述.

有没有人使用TPT和EF投入生产,是否有任何变通方法意味着我不必:a)将模式转换为TPH(这与我尝试用我的数据库设计实现的所有内容相反 - urrrgghh!)?b)用另一个ORM重写?

我看到它的方式,我应该能够在EF(可能使用EFExtensions)中添加对存储过程的引用,该引用具有仅选择我需要的字段的TSQL,甚至使用EF为怪物UNION生成的代码在SP内部/ JOIN将阻止每次调用时生成SQL - 这不是我打算做的事情,但是你明白了.

我发现的杀手是,当我选择链接到基表的实体列表时(但我选择的实体不是子类表),我想按基表的pk进行过滤,我.Include("BaseClassTableName")允许我过滤使用x=>x.BaseClass.PK == 1和访问其他属性,它也在这里执行母SQL生成.

我不能使用EF4,因为我只限于安装了3.5 SP1的.net 2.0运行时.

有没有人有任何摆脱这个烂摊子的经历?

Cra*_*ntz 2

这似乎有点混乱。您正在谈论 TPH,但是当您说:

在我看来,我应该能够从 EF 内添加对存储过程的引用(可能使用 EFExtensions),该存储过程的 TSQL 仅选择我需要的字段,甚至使用 EF 为怪物 UNION 生成的代码SP 内的 /JOIN 会阻止每次调用时生成 SQL - 这不是我想要做的事情,但你明白了。

嗯,这就是每个具体类的表映射(使用过程而不是表,但映射仍然是 TPC...)。EF 支持 TPC,但设计者不支持。如果您获得 CTP ,您可以在代码优先中执行此操作

如果您限制查询,您首选的使用过程的解决方案将导致性能问题,如下所示:

var q = from c in Context.SomeChild
        where c.SomeAssociation.Foo == foo
        select c;
Run Code Online (Sandbox Code Playgroud)

数据库优化器无法看透过程实现,因此您可以获得结果的完整扫描。

因此,在您告诉自己这将修复您的结果之前,请仔细检查该假设。

请注意,您始终可以使用ObjectContext.ExecuteStoreQuery为任何映射策略指定自定义 SQL 。

然而,在执行任何操作之前,请考虑一下,正如 RPM1984 指出的那样,您的设计似乎过度使用了继承。我喜欢NHibernate in Action中的这句话

[A]问问自己,将继承重新建模为对象模型中的委托是否会更好。由于与持久性或 ORM 无关的各种原因,通常最好避免复杂的继承。[您的 ORM] 充当对象模型和关系模型之间的缓冲区,但这并不意味着您在设计对象模型时可以完全忽略持久性问题。