Share and Enjoy !

First Step on How to Auto Generate Created / Updated Field in EF Core

On a recent Entity Framework (EF) Core project we implemented a common pattern used to set property values for our entities / database objects. In this case, to auto generate created / updated field in EF Core.

Entity Framework Core is used by .NET developers to work with a database using .NET objects. It is an Object Relational Mapper (ORM) which uses tables and columns in a relational database to simplify mapping between objects. In a ThreeWill podcast episode, we explain using ASP.NET vs Sharepoint on projects, for those interested in the difference.

In the example provided below, I am using EF Core to set the data values to indicate when the entity was created and last updated. This way, I do not have to worry about setting those values manually.

Three Key Points

Key point #1 – Create a common class from which your models can inherit from, e.g. BaseEntity:

public class BaseEntity
{
  public DateTime CreatedOn { get; set; };
  public DateTime UpdatedOn { get; set; };
}

Key point #2 – Inherit from the common class where appropriate:

public class Company : BaseEntity
{
  public int id { get; set; }
  public string name { get; set; }
}

public class Person : BaseEntity
{
  public int id { get; set; }
  public string name { get; set; }
}

Key point #3 – In your EF Core DbContext class, override the SaveChanges and SaveChangesAsync classes and implement a common method to inspect and set the property values, e.g. OnBeforeSaving:

public class MyApplicationDataContext : DbContext
{
  public override int SaveChanges(bool acceptAllChangesOnSuccess)
  {
   OnBeforeSaving();
   return base.SaveChanges(acceptAllChangesOnSuccess);
  }

  public override async Task<int> SaveChangesAsync(
     bool acceptAllChangesOnSuccess, 
     CancellationToken cancellationToken = default(CancellationToken)
  )
  {
   OnBeforeSaving();
   return (await base.SaveChangesAsync(acceptAllChangesOnSuccess,
                 cancellationToken));
  }

  private void OnBeforeSaving()
  {
    var entries = ChangeTracker.Entries();
    var utcNow = DateTime.UtcNow;

    foreach (var entry in entries)
    {
      // for entities that inherit from BaseEntity,
      // set UpdatedOn / CreatedOn appropriately
      if (entry.Entity is BaseEntity trackable)
      {
        switch (entry.State)
        {
          case EntityState.Modified:
            // set the updated date to "now"
            trackable.UpdatedOn = utcNow;

            // mark property as "don't touch"
            // we don't want to update on a Modify operation
            entry.Property("CreatedOn").IsModified = false;
            break;

          case EntityState.Added:
            // set both updated and created date to "now"
            trackable.CreatedOn = utcNow;
            trackable.UpdatedOn = utcNow;
            break;
        }
      }
    }
  }
}

If the entity inherits from BaseEntity the code will update the appropriate date/time value when the object is created and/or updated.

Pretty cool, huh?

Comment below if this has helped you in any way!

Share and Enjoy !

Related Content: