First, consider that DateTimeOffset
is a better choice if you are going to be storing local times. Alternatively, you could use a UTC-based DateTime
, but I will show DateTimeOffset
in this example. Never store a local-based DateTime
for this purpose, as you will have issues with time zones and daylight saving time. See also: The Case Against DateTime.Now.
Next, consider a common interface that you can use for entities that you wish to track created/updated values.
public interface IDatedEntity
{
DateTimeOffset Created { get; set; }
DateTimeOffset Updated { get; set; }
}
Apply that interface and its properties to the entities you are working with.
public class User : IDatedEntity
{
// ...
public DateTimeOffset Created { get; set; }
public DateTimeOffset Updated { get; set; }
}
Now in your database context, you can attach to the SavingChanges
event and apply the desired behavior:
public class MyContext : DbContext
{
public DbSet<User> Users { get; set; }
public MyContext()
{
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
objectContext.SavingChanges += (sender, args) =>
{
var now = DateTimeOffset.Now;
foreach (var entry in this.ChangeTracker.Entries<IDatedEntity>())
{
var entity = entry.Entity;
switch (entry.State)
{
case EntityState.Added:
entity.Created = now;
entity.Updated = now;
break;
case EntityState.Modified:
entity.Updated = now;
break;
}
}
this.ChangeTracker.DetectChanges();
};
}
}
Note the final call to DetectChanges
, which will ensure that the new updated date values are applied to all modified entities.