代码之家  ›  专栏  ›  技术社区  ›  Abhijeet

在EF Core中自动填充创建的和上次修改的

  •  1
  • Abhijeet  · 技术社区  · 7 年前

    期待构建一个框架(没有直接使用DbSets的存储库模式)来自动填充创建和最后修改的代码,而不是通过代码库吐出这些代码。

    在过去,我尝试在构造函数中填充这些,但这似乎

    .ctor()
        {
            Created = DateTime.Now;
            LastModified = DateTime.Now;
        }
    
    public interface IHasCreationLastModified
        {
            DateTime Created { get; set; }
            DateTime? LastModified { get; set; }
        }
    
    public class Account : IEntity, IHasCreationLastModified
    {
        public long Id { get; set; }
    
        public DateTime Created { get; set; }
        public DateTime? LastModified { get; set; }
        public virtual IdentityUser IdentityUser { get; set; }
    }
    
    2 回复  |  直到 7 年前
        1
  •  25
  •   Ivan Stoev    7 年前

    从v2.1开始,EF Core提供 State change events :

    Tracked 以及 StateChanged ChangeTracker 可用于编写对进入 DbContext 或者改变他们的状态。

    建造师

    ChangeTracker.Tracked += OnEntityTracked;
    ChangeTracker.StateChanged += OnEntityStateChanged;
    

    然后这样做:

    void OnEntityTracked(object sender, EntityTrackedEventArgs e)
    {
        if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IHasCreationLastModified entity)
            entity.Created = DateTime.Now;
    }
    
    void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
    {
        if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
            entity.LastModified = DateTime.Now;
    }
    
        2
  •  4
  •   Gibbon    7 年前

    一个可能的解决方案(我们目前在我工作的地方使用的解决方案)是覆盖 SaveChanges()

    public override int SaveChanges()
    {
        var changedEntriesCopy = ChangeTracker.Entries()
                    .Where(e => e.State == EntityState.Added ||
                    e.State == EntityState.Modified ||
                    e.State == EntityState.Deleted)
                    .ToList();
        var saveTime = DateTime.Now;
    
            foreach (var entityEntry in changedEntriesCopy)
            {
                if (entityEntry.Metadata.FindProperty("Created") != null && entityEntry.Property("Created").CurrentValue == null)
                {
                    entityEntry.Property("Created").CurrentValue = saveTime;
                }
    
                if (entityEntry.Metadata.FindProperty("Updated") != null)
                {
                    entityEntry.Property("Updated").CurrentValue = saveTime;
                }
            }
        return base.SaveChanges();
    }
    

    我们的情况基本上是这样设置的-在我们的情况下创建的是空的,这样当一个新的实体被创建时,在代码中的值是空的,直到创建为止(这使得检查Created是否被填充变得容易)。