SaveChanges() in DbContext - Detecting updated entities

c# dbcontext entity-framework savechanges

Question

The SaveChanges() function in the Entity Framework 4.1 DbContext class has been modified by me.

This is how my override looks:

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;

}

Let's say there are two entities in the context, and both of them have the modified status (EntityState.Modified). One of them differs from the underlying database record because it has been altered. The other was simply identified as being distinct from the underlying database record.

How can I determine which of the two entities that used SaveChanges() really updated a database entry and which one wasn't truly changed at all?

1
6
11/14/2011 8:40:17 PM

Accepted Answer

This is how our code works. The generation of proxies and lazy loading are enabled.

You don't need to visit the database when proxy creation is enabled since EF will recognize which attribute changed. Only if another context updated the row would EF fail to recognize it (concurrency error); to prevent this, utilize the RowVersion column or property.

During construction:

  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;
          }
      }
  }
3
9/3/2012 8:44:02 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow