How to work with modified entity data
At the moment, in order to check for changes in the entity framework object, I check the database and I go through each object and compare the properties with the updated one if they are updated and also the updated date will change.
I find it very long in code and was wondering if there is a cleaner way to validate changes with an entity. I thought maybe using deepcopy with a comparison object and compare something like below. But I would have to set each of my tables to serialize and I don't know if that is good.
if (Equals(oldentity, newentity))
{
newentity.ModifiedDate = DateTime.Now
}
My current way of tracking changes
if (oldentity.firstname != newentity.firstname || oldentity.lastname != newentity.lastname)
{
newentity.ModifiedDate = DateTime.Now
}
The if statement is a fragment, my object has many properties, so it gets long ...
source to share
You can provide your organization with an interface with CreatedDate
and ModifiedDate
properties:
public interface ITrackedEntity
{
DateTime CreatedDate { get; set; }
DateTime ModifiedDate { get; set; }
}
Then override SaveChanges
and SaveChangesAsync
in DBContext
to handle properties for added and modified objects automatically:
public override int SaveChanges()
{
this.UpdateTrackedEntities();
return base.SaveChanges();
}
public override async Task<int> SaveChangesAsync()
{
this.UpdateTrackedEntities();
return await base.SaveChangesAsync();
}
private void UpdateTrackedEntities()
{
var entities = ChangeTracker.Entries().Where(x => x.Entity is ITrackedEntity && (x.State == EntityState.Added || x.State == EntityState.Modified));
foreach (var entity in entities)
{
if (entity.State == EntityState.Added)
{
((ITrackedEntity)entity.Entity).CreatedDate = DateTime.UtcNow;
}
((ITrackedEntity)entity.Entity).ModifiedDate = DateTime.UtcNow;
}
}
Makes things a lot easier.
source to share
Entity Framework has ChangeTracker in DbContext.
I, for example, override my SaveChanges () context and it can get all the changes made to my entities.
public override int SaveChanges()
{
ChangeTracker.DetectChanges();
var addedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Added).ToList();
var modifiedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Modified).ToList();
var deletedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Deleted).ToList();
//Save info generating the ids
var ret = base.SaveChanges();
//Generate Logs logic
...
return ret;
}
ChangeTracker also takes an object as a parameter if you only want to check one object for changes.
More information on ChangeTracker ( https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbchangetracker(v=vs.113).aspx )
source to share