Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Code First DateTime field update on modification

I have the following entity:

public class User
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string UserAddress { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime? UpdateDate { get; set; }
}

How can I make the UpdateDate field of the User entity become the server DateTime on an update? That is to say, whenever an entity in the database becomes modified, the UpdateDate field changes to that exact date and time as well as if to say UpdateDate = new DateTime(Datetime.Now.Ticks)

like image 888
cristianqr Avatar asked Jul 05 '14 22:07

cristianqr


1 Answers

First, consider that DateTimeOffset is a better choice if you are going to be storing local times. Alternatively, you could use a UTC-based DateTime, but I will show DateTimeOffset in this example. Never store a local-based DateTime for this purpose, as you will have issues with time zones and daylight saving time. See also: The Case Against DateTime.Now.

Next, consider a common interface that you can use for entities that you wish to track created/updated values.

public interface IDatedEntity
{
    DateTimeOffset Created { get; set; }
    DateTimeOffset Updated { get; set; }
}

Apply that interface and its properties to the entities you are working with.

public class User : IDatedEntity
{
    // ...

    public DateTimeOffset Created { get; set; }
    public DateTimeOffset Updated { get; set; }
}

Now in your database context, you can attach to the SavingChanges event and apply the desired behavior:

public class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }

    public MyContext()
    {
        var objectContext = ((IObjectContextAdapter)this).ObjectContext;
        objectContext.SavingChanges += (sender, args) =>
        {
            var now = DateTimeOffset.Now;
            foreach (var entry in this.ChangeTracker.Entries<IDatedEntity>())
            {
                var entity = entry.Entity;
                switch (entry.State)
                {
                    case EntityState.Added:
                        entity.Created = now;
                        entity.Updated = now;
                        break;
                    case EntityState.Modified:
                        entity.Updated = now;
                        break;
                }
            }
            this.ChangeTracker.DetectChanges();
        };
    }
}

Note the final call to DetectChanges, which will ensure that the new updated date values are applied to all modified entities.

like image 111
Matt Johnson-Pint Avatar answered Nov 15 '22 07:11

Matt Johnson-Pint