DbContext SaveChanges() - Detecting updated entities

11,976

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;
          }
      }
  }
Share:
11,976
FantasticJamieBurns
Author by

FantasticJamieBurns

Updated on June 28, 2022

Comments

  • FantasticJamieBurns
    FantasticJamieBurns almost 2 years

    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?

  • FantasticJamieBurns
    FantasticJamieBurns over 12 years
    Neither proxy creation nor lazy loading is enabled. I would care either way however! I apply auditing to all updates to the database and have a business requirement that only those entities that actually result in a database change get logged. I could try the RowVersion but it feels wrong to add a column to a database just for this purpose. I could also load the underlying entity from the database first and compare. It just seems like DbContext knows that only 1 was updated, I wondered if there was a way from the context alone to find out which.
  • np-hard
    np-hard over 12 years
    i updated my answer with some code sample. BusinessBase is our baseclass for all entities.