DbContext变更跟踪会影响性能吗?

31

我正在将一个应用程序从EF1升级到EF4.1。我使用“ADO.NET DbContext Generator”模板创建了一个DbContext和一组POCO。

当我查询生成的DbContext时,数据库查询部分需要4ms来执行(通过EF Profiler验证)。然后,上下文大约需要40秒(即FORTY!)才能在返回结果给应用程序之前完成它需要做的事情。

EF1处理相同的查询所需时间少于2秒。

关闭AutoDetectChanges、LazyLoading和ProxyGeneration可以节省2-3秒的时间。

使用AsNoTracking()方法可以将总执行时间减少到约3秒。

这表明ChangeTracking是罪魁祸首。

但是我需要ChangeTracking。我必须能够最终持久化所有更改,而无需手动选择哪些实体已被修改。

有什么办法可以解决这个性能问题吗?


1
这个问题在这里已经被讨论了好几次。看起来像是 EFv4.1 中的一个 bug。 - Ladislav Mrnka
3
你可以尝试关闭AutoDetectChanges / 使用AsNoTracking,但同时创建跟踪代理(所有属性必须是虚拟的)。我想知道这是否会跟踪更改,但现在无法自行测试。 - Ladislav Mrnka
你是如何创建实体的?这个错误表示你正在尝试将集合设置为已经由“EntityCollection”初始化的导航属性。 - Ladislav Mrnka
1
我看到你也在MSDN论坛上问过这个问题。请补充说明,当使用EFv4与POCOs时性能也很差。 - Ladislav Mrnka
1
@程序员们在处理导航属性时遇到问题,尝试将其设置为虚拟并启用ProxyGeneration = true:不要实例化和分配任何集合。代理生成会自动处理这一点。然而,要获取代理对象,您需要使用DbSet.Create来创建它。简单地使用"new"进行实例化是不够的。 - Alex Maker
显示剩余8条评论
2个回答

1
这里有一个问题:技术文档documentation的最后提到的技巧是否有用?或者,我使用了流畅接口来声明性地说明在给定事务中哪些实体确实不会更改,以及哪些可能会更改(不可变 vs 可变)。例如,如果我要保存的实体是聚合根,其中根或其实体引用“refdata”项,则此启发式方法可以防止许多写操作,因为不可变项不需要被跟踪。所有可变项目都将被写入而没有检查(这是一个弱点...也许可以接受,也可能不行)。
我正是在使用通用存储库模式时使用这种方法,因为我不想跟踪更改或为每种情况实现特定策略。如果这还不够,也许在上下文之外滚动自己的更改跟踪并根据需要添加实体就可以了。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接