我最近将我的实体模型从使用 4.1 的 ObjectContext 移动到使用 5.0 的 DbContext。我开始后悔这样做,因为我注意到使用 DbContext 与 ObjectContext 的查询性能很差。这是测试场景:
两种上下文都使用具有大约 600 个表的相同数据库。两者都关闭了 LazyLoading 和 ProxyCreation(代码示例中未显示)。两者都有预先生成的视图。
测试首先进行 1 次调用以加载元数据工作区。然后在一个执行 100 次的 for 循环中,我新建一个上下文并进行一次调用,该调用采用前 10 次。(我在 for 循环内创建上下文,因为这模拟了在 WCF 服务中使用,这将创建每次的上下文)
for (int i = 0; i < 100; i++)
{
using (MyEntities db = new MyEntities())
{
var a = db.MyObject.Take(10).ToList();
}
}
当我使用 ObjectContext 运行它时,大约需要 4.5 秒。当我使用 DbContext 运行它时,大约需要 17 秒。我使用 RedGate 的性能分析器对此进行了分析。对于 DbContext,罪魁祸首似乎是一个名为 UpdateEntitySetMappings 的方法。这在每个查询中都会调用,并且似乎检索元数据工作空间并循环遍历 OSpace 中的每个项目。AsNoTracking 没有帮助。
编辑:为了提供更好的细节,问题与 DbSet 与 ObjectSet 的创建\初始化有关,而不是实际查询。当我使用 ObjectContext 进行调用时,创建 ObjectSet 平均需要 42 毫秒。当我使用 DbContext 进行调用时,创建内部数据库集大约需要 140 毫秒。ObjectSet 和 DbSet 都从元数据工作区进行一些实体集映射查找。我注意到的是,DbSet 为工作区中的所有类型执行此操作,而 ObjectSet 没有。我猜(还没有尝试过)具有较少表的模型的性能差异较小。