使用EF4.1进行动态流畅映射

时间:2012-03-19 15:16:54

标签: reflection entity-framework-4.1 linq-expressions

我想动态创建我的数据模型以使用一些现有的类和自定义XML映射文件,因为我有很多现有的表和许多现有的业务类(可能很疯狂,我不知道)。

对于使用不同列名的属性或者与我想要调用的现有列不对应的属性.Ignore()和.HasColumnName()但是我想用它来做。

所以我希望能够像这样进行调用,但我想基于反射和使用Linq.Expressions的XML配置文件动态制作它们(我从来没有使用过它):

modelBuilder.Entity<Product>().Property(p => p.QuantityInStock).HasColumnName("UnitsInStock");

modelBuilder.Entity<Product>().Ignore(p => p.QuantityInStock);

这就是我正在尝试的(最终我会引用我的XML地图来确定要映射的属性和要忽略的属性):

Type entityType = typeof(Product);

var config = modelBuilder.GetType().GetMethod("Entity")
    .MakeGenericMethod(entityType)
    .Invoke(modelBuilder, null);

var ignore = config.GetType().GetMethod("Ignore").MakeGenericMethod(entityType);

var paramEx = Expression.Parameter(entityType);
var lambdaEx = Expression.Lambda(Expression.Property(paramEx, "QuantityInStock"), paramEx);

ignore.Invoke(config, new[] { lambdaEx });

但是我的lambda表达不对:

Object of type 'System.Linq.Expressions.Expression`1[System.Func`2[ConsoleApplication2.Product,System.Int16]]' 
cannot be converted to type 
'System.Linq.Expressions.Expression`1[System.Func`2[ConsoleApplication2.Product,ConsoleApplication2.Product]]'.

2 个答案:

答案 0 :(得分:1)

Ignore方法的泛型类型参数是错误的。将您的代码更改为:

var paramEx = Expression.Parameter(entityType);
var prop = Expression.Property(paramEx, "QuantityInStock");
var lambdaEx = Expression.Lambda(prop, paramEx);
var ignore = config.GetType().GetMethod("Ignore").MakeGenericMethod(prop.Type);

编辑:致电HasColumnName

var property = config.GetType().GetMethod("Property", new Type[] { lambdaEx.GetType() });
var hasColumnName = property.ReturnType.GetMethod("HasColumnName");

hasColumnName.Invoke(
    property.Invoke(config, new[] { lambdaEx }),
    new[] { "UnitsInStock" });

但是,这对于从long或类似的重载列表中排除的结构不起作用,property的值在这些情况下为null。因此,您必须使用Property搜索通用GetMethods方法并选择适当的方法(Nullable<T>参数中包含或不包含Expression类型。

答案 1 :(得分:0)

IMO这不是Fluent API的预期目的。 Fluent API的全部目的是提供更易读,更简单的配置方式,同时为您提供编译时的安全性。我没有看到这种方法。

外部化配置的更好方法是使用EntityTypeConfiguration类并将其添加到ModelBuilder