ef6中的自动CreatedAt和UpdatedAt字段OnModelCreating()

prz*_*adu 3 c# entity-framework-6 asp.net-mvc-5

我的模型中有列CreatedAtUpdatedAtUser.

User.cs

public string Name { get; set; }
public DateTime? CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
Run Code Online (Sandbox Code Playgroud)

需求

  • 当我们SaveChanges()的用户记录,CreatedAtUpdatedAt应自动保存如:DateTime.UtcNow
  • 当我更新User记录时,只有UpdatedAt列应该更新到当前日期时间.
  • 这应该自动发生在所有其他模型上,可能是一些配置OnModelCreating().
  • 我希望这种行为能够latest从数据库和其他地方查找记录.
  • 我正在使用code first迁移方法
  • 我正在使用MySQL服务器MySql.Data,MySql.Data.Entity.EF6.

UPDATE

我添加了BaseEntity.cs模型

public abstract class BaseEntity
    {
        public DateTime CreatedAt { get; set; }
        public DateTime UpdatedAt { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

从BaseEntity继承用户

public class User : BaseEntity
{
  public int Id { get; set; }
  public int FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和更新的迁移包括 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()"));"
Run Code Online (Sandbox Code Playgroud)

现在,需要一种方法来修复UpdatedAt每个更新中的列.

prz*_*adu 13

最后,找到我的问题的解决方案.因为我们可以将数据库从或更改MySql为,所以使用sql查询添加默认值似乎不是正确的解决方案.postgresqlMs Sql server

这是我如何解决它.

添加Base模型

 public abstract class BaseEntity
 {
    public DateTime? CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
 }
Run Code Online (Sandbox Code Playgroud)

从这个基础模型继承你的所有模型,就我而言 User

public class User : BaseEntity
{
  public int Id { get; set; }
  public int FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用代码优先方法,请不要忘记生成迁移.迁移应该足够简单:

例:

AddColumn("dbo.Users", "CreatedAt", c => c.DateTime(precision: 0));
AddColumn("dbo.Users", "UpdatedAt", c => c.DateTime(precision: 0));
Run Code Online (Sandbox Code Playgroud)

最后一步是覆盖SaveChanges()SaveChangesAsync()在您的上下文中:

public class MyDbContext : DbContext
{
    public DbSet<User> Users { get; set; }

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

    public override async Task<int> SaveChangesAsync()
    {
        AddTimestamps();
        return await 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)