使用Entity Framework 5 Code First将CreatedDate添加到实体

Bri*_*den 29 entity-framework code-first ef-code-first ef-migrations entity-framework-5

我正在尝试向CreatedDate我的模型中的实体添加属性,并且正在使用EF5 Code First.我希望这个日期一旦设置就不会改变,我希望它是一个UTC日期.我不想使用构造函数,因为我在模型中有许多实体要从包含该CreatedDate属性的抽象类继承,并且我不能使用接口强制构造函数.

我已经尝试了不同的数据注释和我试图写一个数据库初始化,将拿起一个特定的实体类型和写有一个ALTER约束getdate()正确的默认值table_namecolumn_name,但我一直没能正确地写代码.

请不要向我推荐AuditDbContext - 实体框架审计上下文EntityFramework.Extended工具,因为它们不能满足我的需要.

UPDATE

CreatedDate是空的SaveChanges()因为我将ViewModel传递给我的视图,它正确地没有调用其中的审计属性CreatedDate.即使我将模型传递给我的视图,我也不会CreatedDate在视图中编辑或存储它.

在这里读到我可以添加[DatabaseGenerated(DatabaseGeneratedOption.Identity)],这将告诉EF CreatedDate在插入和更新后正确存储,但不允许我的应用程序更改它:但我只是Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to OFF通过添加此属性得到错误.

我即将切换到EF Model First,因为这个简单的数据库要求在Code First中实现是荒谬的.

Rus*_*ine 69

我是这样做的:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedDate{ get; set; }
Run Code Online (Sandbox Code Playgroud)

在我的迁移的Up()方法中:

AddColumn("Agents", "CreatedDate", n => n.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));
Run Code Online (Sandbox Code Playgroud)

  • 我在这里找到了一个更好的方法:https://andy.mehalick.com/2014/02/06/ef6-adding-a-created-datetime-column-automatically-with-code-first-migrations (4认同)

Ste*_*ler 28

覆盖上下文中的SaveChanges-Method:

public override int SaveChanges()
{
  DateTime saveTime = DateTime.UtcNow;
  foreach (var entry in this.ChangeTracker.Entries().Where(e => e.State == (EntityState) System.Data.EntityState.Added))
   {
     if (entry.Property("CreatedDate").CurrentValue == null)
       entry.Property("CreatedDate").CurrentValue = saveTime;
    }
    return base.SaveChanges();

}
Run Code Online (Sandbox Code Playgroud)

因评论而更新:仅新添加的实体将设置其日期.

  • 不确定我是否理解正确.现在是晚上,我可能已经喝酒 - 抱歉.但是如果CreatedDate不可用于上下文:那么数据库触发器如何.(是的,当我提出*触发*时,肯定会喝酒) (6认同)
  • 您应该存储`DateTime.UtcNow`而不是本地日期. (3认同)

gun*_*sus 6

与斯蒂芬斯的答案类似,但具有反射,并且还忽略所有用户(外部)更新创建/更新时间。显示要点

  public override int SaveChanges()
        {
            foreach (var entry in ChangeTracker.Entries().Where(x => x.Entity.GetType().GetProperty("CreatedTime") != null))
            {
                if (entry.State == EntityState.Added)
                {
                    entry.Property("CreatedTime").CurrentValue = DateTime.Now;
                }
                else if (entry.State == EntityState.Modified)
                {
                    // Ignore the CreatedTime updates on Modified entities. 
                    entry.Property("CreatedTime").IsModified = false;
                }

                // Always set UpdatedTime. Assuming all entities having CreatedTime property
                // Also have UpdatedTime
                // entry.Property("UpdatedTime").CurrentValue = DateTime.Now;
                // I moved this part to another foreach loop
            }

            foreach (var entry in ChangeTracker.Entries().Where(
                e => 
                    e.Entity.GetType().GetProperty("UpdatedTime") != null && 
                    e.State == EntityState.Modified || 
                    e.State == EntityState.Added))
            {
                entry.Property("UpdatedTime").CurrentValue = DateTime.Now;
            }

            return base.SaveChanges();
        }
Run Code Online (Sandbox Code Playgroud)