【问题标题】:DbContext.Entry performance issueDbContext.Entry 性能问题
【发布时间】:2012-09-25 07:14:37
【问题描述】:

按照 Julia Lermas 的书“DbContext”关于跟踪更改的 N 层解决方案,我为每个实体提供了一个 State 属性和一个 OriginalValues 字典(通过 IObjectWithState)。构建实体后,我将原始值复制到此字典。请参阅本书的示例 (4-23):

public BreakAwayContext()
{
  ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += (sender, args) =>
  {
      var entity = args.Entity as IObjectWithState;
      if (entity != null)
      {
        entity.State = State.Unchanged;
        entity.OriginalValues = BuildOriginalValues(this.Entry(entity).OriginalValues);
      }
    };
}

在 BreakAwayContext(继承自 DbContext)的构造函数中,ObjectMaterialized 事件被捕获。为了检索实体的原始值,通过调用 this.Entry(entity) 从上下文中检索 DbEntityEntry。这个电话正在减慢这个过程。此事件处理程序 80% 的时间都花在此调用上。

是否有更快的方法来检索原始值或实体 DbEntityEntry?

【问题讨论】:

  • 您是否尝试过她的其他建议,改为存储已更改值的列表?我认为存储原始值会很昂贵,因此在我的多层(多平台)解决方案中,我存储了一个逗号分隔的列表,其中包含更改的属性(在 Delphi 中,通过使用 .Net 中的 T4 模板覆盖 Delphi 中每个属性的设置器)首先)。在 DAL 中,当发送实体(或 DTO)以进行更新时,我会遍历并将每个更改的属性标记为已修改。这并没有说明检索原始值的更快方法,但它将实现断开连接的更改跟踪。

标签: entity-framework dbcontext entity-framework-5


【解决方案1】:

Context.Entry() 调用DetectChanges(),这取决于上下文中对象的数量,并且可能非常慢。在您的情况下,您可以替换为更快的版本((IObjectContextAdapter) ctx).ObjectContext.ObjectStateManager.GetObjectStateEntry(obj);

【讨论】:

  • 谢谢!我刚刚换掉了我的代码以使用您的替代方法。我从 8 秒到 0.003 时收到状态电话
  • 太棒了!将状态调用从 4 秒缩短到几乎 0!我用过 ((IObjectContextAdapter) ctx).ObjectContext.ObjectStateManager.GetObjectStateEntry(obj).ChangeState(EntityState.Modified);
猜你喜欢
  • 2017-04-13
  • 2022-01-04
  • 2010-09-05
  • 2015-05-28
  • 2015-06-20
  • 2018-09-27
  • 2017-04-25
  • 2015-08-02
相关资源
最近更新 更多