Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DbContext SaveChanges() - Detecting updated entities

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?

like image 797
FantasticJamieBurns Avatar asked Nov 14 '11 20:11

FantasticJamieBurns


People also ask

What does the DbContext SaveChanges () method return?

Returns. The number of state entries written to the underlying database. This can include state entries for entities and/or relationships.

How does EF core detect changes?

EF Core change tracking works best when the same DbContext instance is used to both query for entities and update them by calling SaveChanges. This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called.

How does DbContext change state of entity?

This can be achieved in several ways: setting the EntityState for the entity explicitly; using the DbContext. Update method (which is new in EF Core); using the DbContext. Attach method and then "walking the object graph" to set the state of individual properties within the graph explicitly.

How does Entity Framework keep track of changes?

The Change Tracking tracks changes while adding new record(s) to the entity collection, modifying or removing existing entities. Then all the changes are kept by the DbContext level. These track changes are lost if they are not saved before the DbContext object is destroyed.


1 Answers

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;
          }
      }
  }
like image 114
np-hard Avatar answered Sep 30 '22 07:09

np-hard