Entity Framework: Setting update timestamp

前端 未结 4 1526
囚心锁ツ
囚心锁ツ 2020-12-29 13:14

All of our database tables have UpdateUserID and UpdateTS. I\'d like to have this set if my entity has changes. Is there a way I can have this update on the spot condition

相关标签:
4条回答
  • 2020-12-29 13:28

    Here's an implementation of the other two ideas, with the following considerations

    • Ensure that you either create proxies that automatically detect changes, or that you have manually detected changes, prior to the call to SaveChanges(). If not, the object state will be EntityState.Unmodified, and the last modified timestamp will not be updated.
    • I have expanded the code to also set the last modified timestamp when the object is first created (EntityState.Added)

    The Code

    public interface IHasLastModified
    {
        DateTime? LastModified { get; set; }
    }
    
    public class MyClass : IHasLastModified
    {
        public virtual int Id { get; set; }
    
        public virtual string SomeOtherProperty { get; set; }
    
        public virtual DateTime? LastModified { get; set; }
    }
    
    public class MyContext : DbContext
    {
        public override int SaveChanges()
        {            
            DateTime now = DateTime.UtcNow;
            foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
            {
                if (!entry.IsRelationship)
                {
                    IHasLastModified lastModified = entry.Entity as IHasLastModified;
                    if (lastModified != null)
                        lastModified.LastModified = now;
                }
            }
    
            return base.SaveChanges();
        }
    
    0 讨论(0)
  • 2020-12-29 13:35

    I call this extension method before calling context.SaveChanges():

    public static void SetLastModified(this ObjectContext context, DateTime dateTime)
    {
        DateTime now = DateTime.UtcNow;
        foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
        {
            if (!entry.IsRelationship)
            {
                IHasLastModified lastModified = entry.Entity as IHasLastModified;
                if (lastModified != null)
                    lastModified.LastModified = now;
            }
        }
    }
    

    I can easily call this code, because I've wrapper the ObjectContext in a repository class. If you're using it bare, you can hook up the ObjectContext.SavingChanges event to do something similar.

    0 讨论(0)
  • 2020-12-29 13:36

    You should be able to handle the SavingChanges event (example here) and perform logic as outlined by @sander

    0 讨论(0)
  • 2020-12-29 13:44

    I couldn't get the solution proposed by @eric-j to work, it only set the dates when creating a new object but not when updating.

    I found this solution and modified it to look similar. Have tried out it, and it works like a charm.

    public override int SaveChanges()
    {
        var now = DateTime.UtcNow;
    
        var entries = ChangeTracker
            .Entries()
            .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
    
        foreach (var entry in entries)
        {
            if (entry.Entity is IHasLastModified lastModified)
            {
                lastModified.LastModified = now;
                if (entry.State == EntityState.Added)
                {
                    lastModified.CreatedDate = now;
                }
            }
        }
    
        return base.SaveChanges();
    }
    
    0 讨论(0)
提交回复
热议问题