更智能的实体框架Codefirst流畅的API

Sti*_*son 11 c# sql-server entity-framework ef-code-first

我需要在所有DateTime和DateTime上使用Sql Server的"datetime2"类型?我所有实体对象的属性.这通常使用流畅的API完成,如下所示:

modelBuilder.Entity<Mail>().Property(c => c.SendTime).HasColumnType("datetime2");
Run Code Online (Sandbox Code Playgroud)

但是,我不希望手动为每个实体类型中的每个DateTime字段执行此操作.(我没有可以放置所有DateTime属性的公共基类型,因为DateTime属性特定于定义它们的实体类型).

简短的问题:我的选择是什么?

长期的问题:我正在考虑使用反射并做了一个尝试,但它变得非常混乱,因为似乎流畅的API不适合这种工作,因为我不得不通过反射调用通用的流畅API方法.这是我的混乱尝试:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        var genericEntityMethod = modelBuilder.GetType().GetMethod("Entity");
        var entityTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterface("IEntity") != null);
        foreach (var t in entityTypes) {
            var props = t.GetProperties().Where(p => 
                p.GetSetMethod() != null && 
                p.GetGetMethod() != null && 
                (p.PropertyType == typeof (DateTime) ||  
                p.PropertyType == typeof(DateTime?)));
            foreach (var propertyInfo in props) {
                var entityMethod = genericEntityMethod.MakeGenericMethod(t.GetType());
                var entityTypeConfiguration = entityMethod.Invoke(modelBuilder,null);
                var lambdaExpression = Expression.Lambda(Expression.MakeMemberAccess(Expression.Parameter(t), propertyInfo), Expression.Parameter(t));

                //var propertyMethod = entityTypeConfiguration.GetType().GetMethod("Property");  // Cant get this to work
                var propertyMethods = entityTypeConfiguration.GetType().GetMethods().Where(m => m.ReturnType == typeof(DateTimePropertyConfiguration)).ToList();
                var propertyMethod = propertyInfo.PropertyType == typeof (DateTime) ? propertyMethods[0] : propertyMethods[1];

               var dateTimePropertyConfiguration = propertyMethod.Invoke(entityTypeConfiguration, new object[] {lambdaExpression});
                var hasColumnTypeMethod = entityTypeConfiguration.GetType().GetMethod("HasColumnType");
                hasColumnTypeMethod.Invoke(dateTimePropertyConfiguration, new object[]{ "datetime2" });
            }
        }
        base.OnModelCreating(modelBuilder);
    }
Run Code Online (Sandbox Code Playgroud)

这行失败了:

                   var dateTimePropertyConfiguration = propertyMethod.Invoke(entityTypeConfiguration, new object[] {lambdaExpression});
Run Code Online (Sandbox Code Playgroud)

出现此错误(Entities.Order是我的具有DateTime属性的实体对象之一):

Object of type 'System.Linq.Expressions.Expression`1[System.Func`2[Entities.Order,System.Nullable`1[System.DateTime]]]' cannot be converted to type 'System.Linq.Expressions.Expression`1[System.Func`2[System.RuntimeType,System.Nullable`1[System.DateTime]]]
Run Code Online (Sandbox Code Playgroud)

任何人都可以用这种反射方法或更好的方式帮助我,给我一个简单的方法来避免手动编写大量流畅的api东西吗?

Lad*_*nka 4

更好的方法。不幸的是,该方法基于 EF6 中可用的自定义约定。您可以尝试EF6 Alpha 2并自行使用自定义约定 - 本演练包含符合您确切要求的示例。

要通过反射解决您的问题,请查看此博客文章。描述了用反射生成映射的代码(应该有相关的开源项目)。