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?
Returns. The number of state entries written to the underlying database. This can include state entries for entities and/or relationships.
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.
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.
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.
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;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With