Populate Created and LastModified automagically in EF Core

c#, ef-core-2.1, entity-framework, entity-framework-core

Solution

Starting with v2.1, EF Core provides State change events:

New `Tracked` And `StateChanged` events on `ChangeTracker` can be used to write logic that reacts to entities entering the `DbContext` or changing their state.

You can subscribe to these events from inside your `DbContext` constructor

ChangeTracker.Tracked += OnEntityTracked;
ChangeTracker.StateChanged += OnEntityStateChanged;

and do something like this:

void OnEntityTracked(object sender, EntityTrackedEventArgs e)
{
    if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IHasCreationLastModified entity)
        entity.Created = DateTime.Now;
}

void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
    if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
        entity.LastModified = DateTime.Now;
}

Problem

Looking forward to build a framework, (No repository pattern to working with DbSets directly) to autopopulate Created and last modified automatically, rather than spitting out these codes through out code base. Could you point me out in right direction how to achieve it. In past I tried populating these in constructors, however that seems like a nasty code and every time we pull up somting from database EF change tracking will mark the entity as modified. ``` .ctor() { Created = DateTime.Now; LastModified = DateTime.Now; } public interface IHasCreationLastModified { DateTime Created { get; set; } DateTime? LastModified { get; set; } } public class Account : IEntity, IHasCreationLastModified { public long Id { get; set; } public DateTime Created { get; set; } public DateTime? LastModified { get; set; } public virtual IdentityUser IdentityUser { get; set; } } ```

Original source