Den*_*nis 5 c# entity-framework
我的应用程序使用实体框架 6.1.0 和DbContextAPI。
它是某种 CAD 系统,旨在编辑一些工程文档。为了检测文档中更改的事实,我正在使用DbContext.ChangeTracker.HasChanges.
当文档具有大量数据(大约 20-25 万个实体)时,DbContext.ChangeTracker.HasChanges运行速度非常慢。由于此代码用于启用/禁用“保存”命令,因此它从 UI 线程执行得相当频繁。这反过来又会影响应用程序的性能。
我重写了这个片段:
private Lazy<DbContext> context;
public bool HasChanges
{
get
{
if (!context.IsValueCreated)
{
return false;
}
return context.Value.ChangeTracker.HasChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个:
public bool HasChanges
{
get
{
if (!context.IsValueCreated)
{
return false;
}
var objectStateManager = ((IObjectContextAdapter)context.Value).ObjectContext.ObjectStateManager;
return
objectStateManager.GetObjectStateEntries(EntityState.Added).Any() ||
objectStateManager.GetObjectStateEntries(EntityState.Deleted).Any() ||
objectStateManager.GetObjectStateEntries(EntityState.Modified).Any();
}
}
Run Code Online (Sandbox Code Playgroud)
而且(这是一个奇迹!)一切都运行得非常快。
看起来DbChangeTracker.HasChanges实施并不是最佳的。我错过了什么吗?
在第一个代码片段中,HasChanges 的调用链涉及对 DetectChanges 的调用。使用快照更改跟踪时,DetectChanges 会遍历所有跟踪的实体以确定是否有任何更改,以便 HasChanges 将返回正确的结果。
第二个代码片段不调用 DetectChanges,而只是向状态管理器询问它已经知道的状态。因此,如果实体已被修改但尚未检测到,则第二个代码片段可能会返回错误的结果。
有几种方法可以处理此问题,其中之一是使用更改跟踪代理而不是快照更改跟踪。我写了一个关于 DetectChanges 的博客系列,详细描述了各种选项和权衡:http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do /。我建议您仔细阅读,以便您可以就哪种更改跟踪最适合您的应用程序做出明智的选择。
| 归档时间: |
|
| 查看次数: |
5445 次 |
| 最近记录: |