I want to get changes occured in an entity and related datas attached to it.
I know how to get the property names that have changed in one entity:
dbContext.Entry(entity).Properties.Where(x => x.IsModified).Select(x => x.Metadata.Name).ToList();
How to do the same for related data in navigation properties ?
In Entity Framework, change tracking is enabled by default. You can also disable change tracking by setting the AutoDetectChangesEnabled property of DbContext to false. If this property is set to true then the Entity Framework maintains the state of entities.
By default, EF Core creates a snapshot of every entity's property values when it is first tracked by a DbContext instance. The values stored in this snapshot are then compared against the current values of the entity in order to determine which property values have changed.
No-Tracking query using AsNoTracking() extention method The AsNoTracking() extension method returns a new query and returned entities do not track by the context. It means that EF does not perform any additional task to store the retrieve entities for tracking.
AsNoTracking(IQueryable)Returns a new query where the entities returned will not be cached in the DbContext or ObjectContext. This method works by calling the AsNoTracking method of the underlying query object.
Based on this article (Entity Change Tracking using DbContext in Entity Framework 6), you should override SaveChanges()
method to track entity changes and its related entities.
public override int SaveChanges()
{
return base.SaveChanges();
}
Actually, You should change the above code to the following sample:
public override int SaveChanges()
{
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified).ToList();
var now = DateTime.UtcNow;
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKey = GetPrimaryKeyValue(change);
foreach(var prop in change.OriginalValues.PropertyNames)
{
var originalValue = change.OriginalValues[prop].ToString();
var currentValue = change.CurrentValues[prop].ToString();
if (originalValue != currentValue) //Only create a log if the value changes
{
//Create the Change Log
}
}
}
return base.SaveChanges();
}
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