Generically correcting data before save with Entity Framework

Been working with Entity Framework (.NET 4.0) for a week now for a data migration job and needed some code that generically corrects string values in the database. You probably also have seen things like empty strings instead of NULL or non-trimmed texts ("United States       ") in "old" databases, and you don't want to apply a correcting function on every column you migrate.

Here's how I've done this (extending the partial class of my ObjectContext):

public partial class MyDatacontext
{
    partial void OnContextCreated()
    {
        SavingChanges += OnSavingChanges;
    }
 
    private void OnSavingChanges(object sender, EventArgs e)
    {
        foreach (var entity in GetPersistingEntities(sender))
        {
            foreach (var propertyInfo in GetStringProperties(entity))
            {
                var value = (string)propertyInfo.GetValue(entity, null);
 
                if (value == null)
                {
                    continue;
                }
 
                if (value.Trim().Length == 0 && IsNullable(propertyInfo))
                {
                    propertyInfo.SetValue(entity, null, null);
                }
                else if (value != value.Trim())
                {
                    propertyInfo.SetValue(entity, value.Trim(), null);
                }
            }
        }
    }

    private IEnumerable<object> GetPersistingEntities(object sender)
    {
        return ((ObjectContext)sender).ObjectStateManager
            .GetObjectStateEntries(EntityState.Added | EntityState.Modified)

            .Select(e => e.Entity);
    }

   
private IEnumerable<PropertyInfo> GetStringProperties(object entity)
    {
        return entity.GetType().GetProperties()
           
.Where(pi => pi.PropertyType == typeof(string));
    }

   
private bool IsNullable(PropertyInfo propertyInfo)
    {
        return ((EdmScalarPropertyAttribute)propertyInfo

            .GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false)
            .Single()).IsNullable;
    }
}

 

Obviously you can use similar code for other generic corrections.

3 Comments

Comments have been disabled for this content.