Skip to content

Instantly share code, notes, and snippets.

@peitor
Forked from anonymous/gist:4133105
Created October 23, 2014 10:57
Show Gist options
  • Save peitor/92e450fd28698184ba11 to your computer and use it in GitHub Desktop.
Save peitor/92e450fd28698184ba11 to your computer and use it in GitHub Desktop.
Updates "DateTime?" as well
/// <summary>
/// Fixes all DateTime and DateTime? properties to be datetime2 in SQL Server.
/// from http://flashfm.blogspot.ch/2011/11/entity-framework-41-code-first-fixing.html
/// </summary>
public static class ContextUtils
{
public static void FixDateTimeColumns(DbContext context, DbModelBuilder modelBuilder)
{
var contextProps = context.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var contextProp in contextProps)
{
var propType = contextProp.PropertyType;
if (!propType.IsGenericType)
continue;
if (propType.GetGenericTypeDefinition() != typeof(DbSet<>))
continue;
var modelType = propType.GetGenericArguments()[0];
// call generic Entity<> method
var entityTypeConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(modelType).Invoke(modelBuilder, null);
var modelProps = modelType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var modelProp in modelProps)
{
var modelPropType = modelProp.PropertyType;
if (modelPropType == typeof(DateTime))
{
var typeParam = Expression.Parameter(modelType, "p");
var body = Expression.Property(typeParam, modelProp);
var lambda = Expression.Lambda(body, typeParam);
// call Property method
var propertyMethod = GetPropertyMethodForDateTime(entityTypeConfig);
var propConfig =
(DateTimePropertyConfiguration)propertyMethod.Invoke(entityTypeConfig, new[] { lambda });
// set the type
propConfig.HasColumnType("datetime2");
}
else if (modelPropType == typeof(DateTime?))
{
var typeParam = Expression.Parameter(modelType, "p");
var body = Expression.Property(typeParam, modelProp);
var lambda = Expression.Lambda(body, typeParam);
// call Property method
var propertyMethod = GetPropertyMethodForNullableDatetime(entityTypeConfig);
var propConfig =
(DateTimePropertyConfiguration)propertyMethod.Invoke(entityTypeConfig, new[] { lambda });
// set the type
propConfig.HasColumnType("datetime2");
}
// prepare lambda (Expression<Func<TStructuralType, DateTime>>)
}
}
}
private static MethodInfo GetPropertyMethodForDateTime(object entityTypeConfig)
{
foreach (var method in entityTypeConfig.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public))
{
if (method.Name == "Property")
{
var mParams = method.GetParameters();
if (mParams.Length == 1)
{
var p = mParams[0];
var f = p.ParameterType.GetGenericArguments()[0]; // Func<TStructuralType, DateTime>
var args = f.GetGenericArguments();
if (args.Length == 2 && args[1] == typeof(DateTime))
{
return method;
}
}
}
}
throw new InvalidOperationException("Could not find appropriate Property method.");
}
private static MethodInfo GetPropertyMethodForNullableDatetime(object entityTypeConfig)
{
foreach (var method in entityTypeConfig.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public))
{
if (method.Name == "Property")
{
var mParams = method.GetParameters();
if (mParams.Length == 1)
{
var p = mParams[0];
var f = p.ParameterType.GetGenericArguments()[0]; // Func<TStructuralType, DateTime>
var args = f.GetGenericArguments();
if (args.Length == 2 && args[1] == typeof(DateTime?))
{
return method;
}
}
}
}
throw new InvalidOperationException("Could not find appropriate Property method.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment