Automatically set created and modified date on each record in EF Core
In all the professional application we would like to know when the particular record is created and updated in the database. Here, you will learn how to insert created date when a new record is added and set the modified date when an existing record is updated without setting dates manually on each entity in EF Core Code-First approach.
EF Core 2.0 includes a feature of generating a date in the database whenever a new record is added using data annotation attribute DatabaseGenerated. However, as of now, EF Core 2.0 does not include a feature to automatically update the modified date.
Consider the following entity with CreatedDate
and UpdatedDate
properties.
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } public DateTime? DateOfBirth { get; set; } public decimal Height { get; set; } public float Weight { get; set; } public DateTime CreatedDate { get; set; } public DateTime UpdatedDate { get; set; } }
In the above entity, the CreatedDate
filed will be saved when a new Student
entity will be saved and UpdatedDate
will be updated when an existing Student
entity will be saved.
Since we want CreatedDate
and UpdatedDate
properties on all entities let’s extract an abstract base class BaseEntity and have Student inherit from it.
public class Student: BaseEntity { public int StudentID { get; set; } public string StudentName { get; set; } public DateTime? DateOfBirth { get; set; } public decimal Height { get; set; } public float Weight { get; set; } } public class BaseEntity{ public DateTime CreatedDate { get; set; } public DateTime UpdatedDate { get; set; } }
EF Core 2.0 does not include any feature for automatically save CreatedDate
and UpdatedDate
. So, we will have to handle it in the SaveChanges() method so that it can be used with all entities. Override the SaveChanges() method in the context class as shown below.
public override int SaveChanges() { var entries = ChangeTracker .Entries() .Where(e => e.Entity is BaseEntity && ( e.State == EntityState.Added || e.State == EntityState.Modified)); foreach (var entityEntry in entries) { ((BaseEntity)entityEntry.Entity).UpdatedDate = DateTime.Now; if (entityEntry.State == EntityState.Added) { ((BaseEntity)entityEntry.Entity).CreatedDate = DateTime.Now; } } return base.SaveChanges(); }
As you can see, in the SaveChanges()
method, we first get all the entity entries who’s entity type is BaseEntity and entity state is added or modified. After that, we set the current date on each entity’s UpdatedDate
property (UpdatedDate
and CreatedDate
will be the same for the new record. You can change this behavior as you want). If an entity state is added then we set the current date to CreatedDate
property.
Now, execute the following code and check the record in the database.
using (var context = new SchoolContext()) { var std = new Student(){ StudentName = "Bill" }; context.Add(std); context.SaveChanges(); }
The above code will insert the following record with CreatedDate
and UpdatedDate
in the Students
table.
Thus, you can keep track of all records in the Entity Framework Core Code-First approach.
Learn how to achieve the same result by using shadow properties in EF Core here.