0

I have the following overide in my ApplicationDBContext so that whnenever a new entity is added or modified it adds a created or modifed timestamp. It works for when I create an entity but seems to fail when I do an update - the modifed datestamp doesnt seem to update?

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

        foreach (var entry in modifiedEntries)
        {
            AuditableEntity entity = entry.Entity as AuditableEntity;
            if (entity != null)
            {
                string userId = System.Threading.Thread.CurrentPrincipal.Identity.GetUserId();
                DateTime now = DateTime.UtcNow;

                if (entry.State == EntityState.Added)
                {
                    entity.CreatedBy = userId;
                    entity.CreatedDate = now;
                }
                else
                {
                    base.Entry(entity).Property(x => x.CreatedBy).IsModified = false;
                    base.Entry(entity).Property(x => x.CreatedDate).IsModified = false;
                }

                entity.ModifiedBy = userId;
                entity.ModifiedDate = now;
            }
        }

        return base.SaveChanges();
    }

This is my controller action to update the model:

  var post = _postRepository.GetPost(viewModel.Id);

 UpdateModel(post, "", includeProperties: new[] { "Subject", "TypeId", "CategoryId" });

 _unitOfWork.Complete();

_unitOfWork.Complete() simply calls the following:

public void Complete()
{
   _context.SaveChanges();
}

The Auditable class is an abstract class whith the Post inherits from:

 public abstract class AuditableEntity 
{
    [ScaffoldColumn(false)]
    public DateTime CreatedDate { get; set; }

    [MaxLength(128)]
    [ScaffoldColumn(false)]
    public string CreatedBy { get; set; }

    [ScaffoldColumn(false)]
    public DateTime ModifiedDate { get; set; }

    [MaxLength(128)]
    [ScaffoldColumn(false)]
    public string ModifiedBy { get; set; }

    public ApplicationUser Creator { get; set; }
    public ApplicationUser Modifier { get; set; }
}

public class Post : AuditableEntity
{
   ...

}

All the fields get updated apart from the modifiedby and modifieddate?

My understanding was that when you call UpdateModel, Entity Framework's automatic change tracking sets the Modified flag on the entity?

adam78
  • 9,668
  • 24
  • 96
  • 207
  • I have the same code (more or less) working. Have you debugged and inspected the EntityState before and after? – Steve Greene Jul 12 '16 at 15:50
  • @SteveGreene I've tried debugging and when it cycles to modifedentries on the savechanges() method it is empty, so basically skipping the foreach loop? – adam78 Jul 12 '16 at 17:43
  • Here is a link to what I used. Similar techniques except interface is used versus abstract class. If your modifiedEntries is empty, maybe try fetching just the modified entries without "x.Entity is AuditableEntity" and see what that returns. http://stackoverflow.com/questions/16554799/datecreated-or-modified-column-entity-framework-or-using-triggers-on-sql-serve/16557167#16557167 – Steve Greene Jul 13 '16 at 13:10

0 Answers0