2015-02-10 39 views
2

我想在动态选择的表上应用简单的“Where”子句。然而,这个子句将应用到的表格字段也是动态的,我无法弄清楚如何使该部分起作用。获取动态表格可正常工作。不能在表达式树的lambda中使用动态委托参数

using (var context = new DBEntities()) 
{ 
    var type = context.GetType(); 
    var tableProperty = type.GetProperty("tableName"); 
    var tableGet = tableProperty.GetMethod; 
    var tableContent = tableGet.Invoke(context, null); 
    var tableQuery = (IQueryable)tableContent; 
    var tableType = tableQuery.ElementType; 

    var pe = Expression.Parameter(tableType, "tableType"); 
    var left = Expression.PropertyOrField(pe, "fieldName"); 
    var right = Expression.Constant("fieldValue"); 
    var predicateBody = Expression.Equal(left, right); 

    var whereCallExpression = Expression.Call(typeof(Queryable), "Where", new[] { tableType }, 
     tableQuery.Expression, Expression.Lambda<Func<tableType, bool>>(predicateBody, pe)); 

    IQueryable<string> results = tableQuery.Provider.CreateQuery<string>(whereCallExpression); 
} 

由于Expression.Lambda<Func<tableType, bool>>(predicateBody, pe)这个代码块不会编译。如果我为与表达式相关的代码硬编码类型,此示例将运行并返回预期结果。

+0

如果你打算做字面上* *的一切动态像这样,你最好不要首先使用EF。使用更多传统的方法来执行本质上已经固有动态的DB查询。 EF有利于将查询限制在那些静态有效的查询中,这是一项只会让您的生活变得艰难的功能。 – Servy 2015-02-10 16:46:14

+0

不幸的是,这个特殊功能的驱动功能在项目开始的几个月后才开始增加。有关该项目的其他一切(99%)与EF完全一致。 – Kibner 2015-02-10 16:52:03

+0

然后让其他99%的项目使用EF,并让这个功能使用别的东西,因为EF不适合它。 – Servy 2015-02-10 16:56:52

回答

1

该代码不编译,因为tableType,类型为System.Type的变量不能用作通用函数的类型参数。

但是,你应该能够让这个编译,并通过与呼叫更换仿制Lambda<Func<...>>调用非通用Lambda运行:

var whereCallExpression = Expression.Call(typeof(Queryable), "Where", new[] { tableType }, 
    tableQuery.Expression, Expression.Lambda(predicateBody, pe)); 
+0

这工作,谢谢!我也必须改变我的最后一行为'IQueryable结果= tableQuery.Provider.CreateQuery(whereCallExpression);' – Kibner 2015-02-10 16:48:38