Monday, September 07, 2009

Auto update columns in Dynamic Data

Lots of people have a requirement to have some columns automatically updated when using Dynamic Data in conjunction with the Entity Framework. These are typically audit type columns such as the ModifiedDate column found in the AdventureWorks database.

The typical solution is to create a handler to trap the event so that you can change the data before it is saved to the database.


public partial class AdventureWorksEntities : global::System.Data.Objects.ObjectContext
    {
        partial void OnContextCreated()
        {
            this.SavingChanges += new EventHandler(OnSavingChanges);
 
        }
        private static void OnSavingChanges(object sender, EventArgs e)
        {
            foreach (ObjectStateEntry entry in ((ObjectContext)sender).ObjectStateManager.GetObjectStateEntries(
                 EntityState.Added | EntityState.Modified))
            {
                int i = entry.CurrentValues.GetOrdinal("ModifiedDate");
                entry.CurrentValues.SetValue(i, DateTime.Now);
            }

This can give you problems if you want a generic version for all tables but not all the tables have the ModifiedDate column and so GetOrdinal throws an exception. An alternative is to use some reflection to check if the Property exists and update accordingly and avoids exceptions being thrown.

foreach (ObjectStateEntry entry in ((ObjectContext)sender).ObjectStateManager.GetObjectStateEntries(
                EntityState.Added | EntityState.Modified))
            {
                // Ignore relationships
                if (!entry.IsRelationship)
                {
                    foreach (PropertyInfo pi in entry.Entity.GetType().GetProperties())
                    {
                        if (pi.Name == "ModifiedDate")
                            pi.SetValue(entry.Entity, DateTime.Now, null);
                    }
                }
            }

No comments:

Post a Comment