DbContext SaveChanges() - 检测更新的实体

发布于 2024-12-15 15:19:55 字数 746 浏览 11 评论 0原文

我已重写 Entity Framework 4.1 DbContext 类中的 SaveChanges() 方法。

我的覆盖如下所示:

public override int SaveChanges() {

    IEnumerable<DbEntityEntry> modifiedEntityEntries = ChangeTracker.Entries().Where( e => e.State == EntityState.Modified );

    Debug.Assert( modifiedEntityEntries.Count() == 2 );

    int savedChanges = base.SaveChanges();

    Debug.Assert( savedChanges == 1 );

    // HELP! At this point, how do I tell Which of the two "Modified" entities actually updated a row in the database?

    return savedChanges;

}

假设上下文中有 2 个实体,并且两者都被标记为已修改 (EntityState.Modified)。其中之一已被修改并且与基础数据库行不同。另一个实际上与底层数据库行没有什么不同,它只是被标记为这样。

在调用 SaveChanges() 后,我如何判断两个实体中哪一个实际更新了数据库中的一行,哪一个根本没有真正修改?

I have overridden the SaveChanges() method in the Entity Framework 4.1 DbContext class.

My override looks like this:

public override int SaveChanges() {

    IEnumerable<DbEntityEntry> modifiedEntityEntries = ChangeTracker.Entries().Where( e => e.State == EntityState.Modified );

    Debug.Assert( modifiedEntityEntries.Count() == 2 );

    int savedChanges = base.SaveChanges();

    Debug.Assert( savedChanges == 1 );

    // HELP! At this point, how do I tell Which of the two "Modified" entities actually updated a row in the database?

    return savedChanges;

}

Assume that there are 2 entities in the context, and both are marked as Modified (EntityState.Modified). One of them has been modified and is different to the underlying database row. The other isn't actually different to the underlying database row, it was just marked as such.

How do I tell after calling SaveChanges() which of the two entities actually updated a row in the database, and which one was not really modified after all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

巨坚强 2024-12-22 15:19:55

这就是我们编写代码的方式。启用延迟加载和代理创建。

请注意,启用代理创建后,EF 将知道哪个属性发生了变化,您无需访问数据库。 EF 唯一不知道的地方是其他上下文是否更改了行(并发错误),以避免您

在构造函数中使用 RowVersion 列/属性:

  public DataContext()
            : base()
  {
      this.Configuration.ProxyCreationEnabled = true;
      this.Configuration.LazyLoadingEnabled = true;
      var objectContext = ((IObjectContextAdapter)this).ObjectContext;
      objectContext.SavingChanges += new EventHandler(objectContext_SavingChanges);
  }

  private void objectContext_SavingChanges(object sender, EventArgs e)
  {
      var objectContext = (ObjectContext)sender;
      var modifiedEntities =
            objectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added
            | System.Data.EntityState.Modified);

      foreach (var entry in modifiedEntities)
      {
          var entity = entry.Entity as BusinessBase;
          if (entity != null)
          {
              entity.ModDateTime = DateTime.Now;
              entity.ModUser = Thread.CurrentPrincipal.Identity.Name;
          }
      }
  }

This is the way we do it our code. Lazy loading and proxy creation is enabled.

Note than when proxy creation is enabled, EF would know which property changed, you dont need to go to database. The only place EF would not know is if some other context changed the row (concurrency error), to avoid that you would use RowVersion column/property

In the constructor:

  public DataContext()
            : base()
  {
      this.Configuration.ProxyCreationEnabled = true;
      this.Configuration.LazyLoadingEnabled = true;
      var objectContext = ((IObjectContextAdapter)this).ObjectContext;
      objectContext.SavingChanges += new EventHandler(objectContext_SavingChanges);
  }

  private void objectContext_SavingChanges(object sender, EventArgs e)
  {
      var objectContext = (ObjectContext)sender;
      var modifiedEntities =
            objectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added
            | System.Data.EntityState.Modified);

      foreach (var entry in modifiedEntities)
      {
          var entity = entry.Entity as BusinessBase;
          if (entity != null)
          {
              entity.ModDateTime = DateTime.Now;
              entity.ModUser = Thread.CurrentPrincipal.Identity.Name;
          }
      }
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文