The title is quite self-explanatory. Is there a built-in mechanism to support Created and Edited timestamps on records in a code-first database in Entity Framework Core?
Something like :created_at
and :updated_at
in Ruby on Rails migrations. I could not find any documentation concerning this. If no out-of-the-box mechanism is present, is there a best practice how to implement those columns?
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.
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.
Lean object-to-database mappers like Dapper have consistently outperformed EF in query performance, but every new release of Microsoft's library has been closing the gap.
Entity Framework Extensions EF Core - InMemory Provider. InMemory is designed to be a general-purpose database for testing and is not designed to mimic a relational database. InMemory will allow you to save data that would violate referential integrity constraints in a relational database.
The non EF Core solutions don't apply to EF Core without some amount of rework. I wanted to allow certain entities to have CreatedAt
and LastModified
timestamps that updated in a reasonably automated way. This is what I ended up doing.
Defined an interface - ITimeStampedModel
that my models could inherit from that required them to have the timestamps I wanted:
public interface ITimeStampedModel
{
DateTime CreatedAt {get; set;}
DateTime LastModified {get; set;}
}
Override SaveChanges
on my DbContext
to look for new or modified models, and update their timestamps appropriately:
public override int SaveChanges()
{
var newEntities = this.ChangeTracker.Entries()
.Where(
x => x.State == EntityState.Added &&
x.Entity != null &&
x.Entity as ITimeStampedModel != null
)
.Select(x => x.Entity as ITimeStampedModel);
var modifiedEntities = this.ChangeTracker.Entries()
.Where(
x => x.State == EntityState.Modified &&
x.Entity != null &&
x.Entity as ITimeStampedModel != null
)
.Select(x => x.Entity as ITimeStampedModel);
foreach (var newEntity in newEntities)
{
newEntity.CreatedAt = DateTime.UtcNow;
newEntity.LastModified = DateTime.UtcNow;
}
foreach (var modifiedEntity in modifiedEntities)
{
modifiedEntity.LastModified = DateTime.UtcNow;
}
return base.SaveChanges();
}
Anyone have a better solution?
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