-
-
Save peitor/92e450fd28698184ba11 to your computer and use it in GitHub Desktop.
Updates "DateTime?" as well
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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