Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core: Built in Created and Edited timestamps [duplicate]

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?

like image 664
lss Avatar asked Oct 25 '17 08:10

lss


People also ask

How does Entity Framework keep track of changes?

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.

How EF detect changes when you update a property value?

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.

Is Dapper faster than EF core?

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.

What is Entityframeworkcore InMemory?

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.


1 Answers

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.

  1. 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;}
    }
    
  2. 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?

like image 75
mattnedrich Avatar answered Nov 11 '22 05:11

mattnedrich