Reputation: 2153
At the moment to check for changes with my entity framework object, I check in the database and I go through each object and compare the properties with the updated, if they are updated then my date modified will be updated as well.
I find that it's getting very lengthy in code and was wondering if there's a cleaner way to check for changes using entity framework. I was thinking maybe using deepcopy with a object comparison and compare something like below. But I would have to set each of my tables to be serialized and I don't know if that's a good thing.
if (Equals(oldentity, newentity))
{
newentity.ModifiedDate = DateTime.Now
}
My current method of tracking changes
if (oldentity.firstname != newentity.firstname || oldentity.lastname != newentity.lastname)
{
newentity.ModifiedDate = DateTime.Now
}
The if statement is a snippet, my entity has many properties so it gets lengthy...
Upvotes: 3
Views: 917
Reputation: 106620
You can give your entity an interface with CreatedDate
and ModifiedDate
properties:
public interface ITrackedEntity
{
DateTime CreatedDate { get; set; }
DateTime ModifiedDate { get; set; }
}
Then override SaveChanges
and SaveChangesAsync
in the DBContext
to handle updating the properties for added and modified entities 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 simpler.
Upvotes: 1
Reputation: 2757
Entity Framework has a ChangeTracker in DbContext.
I for example have a override of my context's SaveChanges() and it is able to get all the changes made in 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 accepts an entity as parameter if you want to check a just a single entity for changes.
More info on ChangeTracker (https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbchangetracker(v=vs.113).aspx)
Upvotes: 0
Reputation: 4274
You can try something like
public bool HasUnsavedChanges(MyObject oldentity)
{
return (YourObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified).Any(x=>x.Id == oldentity.Id));
}
Upvotes: 0