如何自动设置DateCreated和DateUpdated

时间:2014-02-20 15:21:46

标签: c# .net sql-server entity-framework entity-framework-6

如果我有以下实体:

public class PocoWithDates {
    public string PocoName { get; set; }
    public DateTime DateCreated { get; set; }
   public DateTime DateUpdated { get; set; }
}

对应于具有相同名称/属性的SQL Server 2008(R2)表...

我该如何自动: - 在执行INSERT时将DateCreatedDateUpdated字段设置为现在 - 在执行更新时将DateUpdated字段设置为现在

当我自动说,我的意思是我希望能够这样做:

poco.Name = "Changing the name";
repository.Save(); 

不是这个:

poco.Name = "Changing the name";
poco.LastModified = DateTime.Now;
repository.Save();

在幕后,“某事”应该自动更新DateTime字段。什么是“东西”?我正在使用Entity Framework 6.0。 EF可以自动执行此操作吗?我知道MySQL可以做这样的事情。或者在SQL Server中使用触发器/存储过程。但我不希望这样。

此问题是此问题的替代和更改版本: Entity Framework/SQL2008 - How to Automatically Update LastModified fields for Entities?

这个问题为EF 4.0提供了一些很好的解决方案/答案。但是我想用EF6.0加DBContext。如果我有更多的时间,我会尝试调整这些解决方案,让他们在EF6.0中工作。但是现在我想知道是否有人已经解决了这个问题,或者知道如何将EF4.0的自定义SaveChanges()Add()覆盖转录为EF6.0。

3 个答案:

答案 0 :(得分:5)

您可以覆盖DbContext上的SaveChanges()方法,以更新Save()上的DateUpdated值。我会实现一个接口,允许更新一些项目,而不是其他项目。

public interface IEntityAutoDateFields
{
    DateTime DateCreated { get; set; }
    DateTime DateUpdated { get; set; }
}

然后:

public class PocoWithDates : IEntityAutoDateFields
{
    public PocoWithDates()
    {

    }

    public DateTime DateCreated { get; set; }
    public DateTime DateUpdated { get; set; }
}

在你的背景下:

public PocoWithDatesContext : DbContext
{
     public DbSet<PocoWithDates> PocoWithDatesSet { get; set;}

     public override int SaveChanges()
     {
         var now = DateTime.Now;             

         this.ChangeTracker.DetectChanges();
         foreach (var item in this.ChangeTracker.Entries()
                               .Where(i => i.State == EntityState.Added || i.State == EntityState.Modified)
                               .Where(i => i as IEntityAutoDateFields != null))
         {
             if (item.State == EntityState.Added)
             {
                  (item as IEntityAutoDateFields).DateCreated = now;
             }
             (item as IEntityAutoDateFields).DateUpdated = now;
         }
         // Call the SaveChanges method on the context;
         return base.SaveChanges();
     }
}

答案 1 :(得分:1)

这是基于Ben Cull solution。我刚刚添加了处理异步方法SaveChangesAsync()。

1创建基类

public class BaseEntity
{
    public DateTime? DateCreated { get; set; }
    public string UserCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public string UserModified { get; set; }
}

2将Base应用于现有类

public class Student : BaseEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

3覆盖DBContext类

中的SaveOn()和SaveOnSync()
public class SchoolContext : DbContext
{

public override int SaveChanges()
{
    var entities = ChangeTracker.Entries().Where(x => x.Entity is BaseEntity && (x.State == EntityState.Added || x.State == EntityState.Modified));

    var currentUsername = HttpContext.Current != null && HttpContext.Current.User != null
        ? HttpContext.Current.User.Identity.Name
        : "Anonymous";

    foreach (var entity in entities)
    {
        if (entity.State == EntityState.Added)
        {
            ((BaseEntity)entity.Entity).DateCreated = DateTime.Now;
            ((BaseEntity)entity.Entity).UserCreated = currentUsername;
        }

        ((BaseEntity)entity.Entity).DateModified = DateTime.Now;
        ((BaseEntity)entity.Entity).UserModified = currentUsername;
    }

    return base.SaveChanges();
}
}

public override Task<int> SaveChangesAsync(System.Threading.CancellationToken cancellationToken)

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

        var currentUsername = HttpContext.Current != null && HttpContext.Current.User != null
            ? HttpContext.Current.User.Identity.Name : "Anonymous";


        foreach (var entity in entities)
        {
            if (entity.State == EntityState.Added)
            {
                ((BaseEntity)entity.Entity).DateCreated = DateTime.Now;
                ((BaseEntity)entity.Entity).UserCreated = currentUsername;
            }

            ((BaseEntity)entity.Entity).DateModified = DateTime.Now;
            ((BaseEntity)entity.Entity).UserModified = currentUsername;
        }

        return base.SaveChangesAsync(cancellationToken);
    }
    }

答案 2 :(得分:0)

添加一个构造函数,在实体的新实例上设置DateCreated / DateUpdated。

public class PocoWithDates {
    public PocoWithDates()
    {
        this.DateCreated = DateTime.Now;
        this.DateUpdated = this.DateCreated;
    }

    public string PocoName { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateUpdated { get; set; }
}

就自动修改Save()上的DateUpdated而言,您可能希望查看here