2015-02-10 55 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