我最近一直在使用EF4.1 Code First,一切都很好(喜欢MVC),但现在开始遇到重大性能问题。
我有大约20个简单的POCO类派生自单个基类,使用Table-Per-Type EF继承映射:
EF为我提供了一个干净的表层次结构。但是,如果我现在从数据库加载单个对象,就像这样,可能需要几秒钟时间:
DerivedClass derivedObject = context.Set<DerivedClass>().Find(id);
我已经检查了延迟加载已启用,并使用SQL事件探查器将问题缩小到EF创建的SQL查询以检索对象,这与此处的查询结构类似但 很多 更大:
EF Code First: Retrieving a base type queries all derived type tables
由于我有20个派生自同一基类的子类,EF正在进行SQL联合并加入 所有20个表 (即使我只需要两个数据)表 - 对于子类和基类),创建一个包含大约100列的结果表,这是派生+基类中的属性/列的总数。 SQL查询的文本长度超过300KB ,并且在本地计算机上的SQL Server Management Studio中执行查询大约需要3秒来撤消一行数据,这是一个杀手。
我刚才刚刚诊断出这个问题,所以我会非常感谢有关重组代码的任何反馈。我目前的想法是:
通过使用接口而不是基类来展平对象结构,将基类功能复制到所有子类并对表层次结构进行非规范化(非规范化不是主要问题,并且可能更有效率来自db透视,但复制基类功能会很痛苦。)
为所有数据检索创建sprocs,包括延迟加载调用(痛苦但可能且很容易错过调用)。
帮助!我牺牲OO还是EF?!
如果有人知道如何简化EF创建的SQL查询而不必重构我的类结构,那就更好了。