SaveChanges() in DbContext - Detecting updated entities

c# dbcontext entity-framework savechanges

Question

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?

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

Accepted Answer

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;
          }
      }
  }
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