我的 CreatedAt 模型中有 UpdatedAtUser 列。
User.cs

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

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

  • 更新

    我添加了 BaseEntity.cs 模型
    public abstract class BaseEntity
        {
            public DateTime CreatedAt { get; set; }
            public DateTime UpdatedAt { get; set; }
        }
    

    从BaseEntity继承用户
    public class User : BaseEntity
    {
      public int Id { get; set; }
      public int FullName { get; set; }
    }
    

    并更新迁移以包含 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()"));"
    

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

    最佳答案

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

    这是我解决的方法。

    添加Base模型

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

    从该基本模型继承所有模型,在我的情况下为User
    public class User : BaseEntity
    {
      public int Id { get; set; }
      public int FullName { get; set; }
    }
    

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

    例子:
    AddColumn("dbo.Users", "CreatedAt", c => c.DateTime(precision: 0));
    AddColumn("dbo.Users", "UpdatedAt", c => c.DateTime(precision: 0));
    

    最后一步是在您的上下文中覆盖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;
            }
        }
    }
    

    10-05 18:51