Rajagopal
Rajagopal

Reputation: 149

On updating a record in EF

I am using EF code first in my asp.net mvc project. I want an updated_at(DateTime) column in every table. So if I update a record, I want the column value to be set to current DateTime.

public abstract class User
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    [Required]
    public string name { get; set; }
    [Required]
    public string email { get; set; }
    [Required]
    public string password { get; set; }

    private DateTime _created_at;
    private DateTime _updated_at;

    public User()
    {
        _created_at = DateTime.Now;
        _updated_at = DateTime.Now;
    }

    public virtual DateTime created_at
    {
        get
        {
            return this._created_at;
        }
    }

    public virtual DateTime updated_at
    {
        get
        {
            return this._updated_at;
        }
    }
}

How Do I make that happen in EF without writing a TRIGGER in database directly.

Upvotes: 0

Views: 861

Answers (2)

Charlie Brown
Charlie Brown

Reputation: 2825

You should use an interface to define how you want to handle timestamping information in your classes. You can use this same technique for many different things.

public interface ITimeStampable
{
    DateTime created_at {get; set;}
    DateTime updated_at {get; set;}
}

public class User : ITimeStampable
{
    public User(){ 
        created_at = DateTime.Now;
        updated_at = DateTime.Now;
    }
    public DateTime created_at {get; set;}
    public DateTime updated_at {get; set;}
}

void ObjectContext_SavingChanges(object sender, EventArgs e)
{
   var context = sender as ObjectContext;

   foreach (ObjectStateEntry entry in
       context.ObjectStateManager.GetObjectStateEntries(
       EntityState.Modified))
   {
       if (typeof(IAuditable).IsAssignableFrom(entry.Entity.GetType()))
                (entity as IAuditable).ChangeTS = DateTime.Now;
   }
}

Upvotes: 0

sergioadh
sergioadh

Reputation: 1471

In you DbContext constructor use the following:

public MyDbContext()
{
    ((IObjectContextAdapter)this).ObjectContext.SavingChanges += ObjectContext_SavingChanges;
}

void ObjectContext_SavingChanges(object sender, EventArgs e)
{
    // Ensure that we are passed an ObjectContext
    ObjectContext context = sender as ObjectContext;
    if (context != null)
    {
        // Set DateTime to UTC when
        foreach (ObjectStateEntry entry in
            context.ObjectStateManager.GetObjectStateEntries(
            EntityState.Modified))
        {
            if (entry.Entity.GetType().GetProperty("_updated_at") != null)
            {
                dynamic entity = entry.Entity;
                entity._updated_at = DateTime.UtcNow;
                DateTime.SpecifyKind(entity._updated_at, DateTimeKind.Utc);
            }
        }
    }
}

Upvotes: 3

Related Questions