Automatic CreatedAt and UpdatedAt fields OnModelCreating() in ef6

Viewed 9031

I have CreatedAt and UpdatedAt columns in my User model.

User.cs

public string Name { get; set; }
public DateTime? CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }

Requirement

  • When we SaveChanges() user records, CreatedAt and UpdatedAt should automatically saved e.g: DateTime.UtcNow
  • When I update User record, only UpdatedAt column should get updated to current date time.
  • And this should happen automatically for all other models, may be some configuration in OnModelCreating().
  • I want this behavior to find latest records from the database, and other places too.
  • I am using code first migration approach
  • I am using MySQL server, MySql.Data, MySql.Data.Entity.EF6.

UPDATE

I added BaseEntity.cs model

public abstract class BaseEntity
    {
        public DateTime CreatedAt { get; set; }
        public DateTime UpdatedAt { get; set; }
    }

Inheriting User from BaseEntity

public class User : BaseEntity
{
  public int Id { get; set; }
  public int FullName { get; set; }
}

and updated migrations to include defaultValueSql()

AddColumn("dbo.Users", "CreatedAt", c => c.DateTime(nullable: false, precision: 0, defaultValueSql: "NOW()"));
AddColumn("dbo.Users", "UpdatedAt", c => c.DateTime(nullable: false, precision: 0, defaultValueSql: "NOW()"));"

Now, need a way to fix UpdatedAt column in each update.

3 Answers

I saw the @przbadu's post and I had a little difficult. I am using dotnet core 2.2 and my override I needed to change the SaveChangeAsync method to:

public override int SaveChanges()
{
    AddTimestamps();
    return base.SaveChanges();
}

public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
    AddTimestamps();
    return base.SaveChangesAsync();
}

private void AddTimestamps()
{
    var entities = ChangeTracker.Entries()
        .Where(x => x.Entity is BaseEntity && (x.State == EntityState.Added || x.State == EntityState.Modified));

    foreach (var entity in entities)
    {
        var now = DateTime.UtcNow; // current datetime

        if (entity.State == EntityState.Added)
        {
            ((BaseEntity)entity.Entity).CreatedAt = now;
        }
        ((BaseEntity)entity.Entity).UpdatedAt = now;
    }
}
Related