2015-06-02 50 views
0

我有一個使用lambda(語法)創建的Expression<Func<TOwner, object>>類型表達式。它具有成員訪問表達式的某個地方。我想創建表達式來選擇所提到的表達式結果的另一個屬性。 C#的擴展成員訪問表達式

我而言它應該是這樣的:

Expression<Func<MyClient, object>> exStartingPath = x => x.Address; 

Expression<Func<MyClient, object>> exExtendedPath = ExtendSelection(exStartingPath, "Street"); 
//exExtendedPath should be equivalent to x => x.Address.Street 

應該如何ExtendSelection(...)來實現?我應該分解已經存在的表達式並使用一些遍歷技術來編寫新的表達式,還是有任何可以「附加」成員選擇的API?

+0

嘗試看到這個[文章](http://stackoverflow.com/questions/2797261/mutating-the-expression-tree-of-a-predicate-to-target-another-type?rq=1 )和[this](http://stackoverflow.com/questions/29893512/convert-an-expressionfunct-bool-to-an-expressionfunct1-bool-so-that-t-is/29894371#29894371) – Grundy

+0

@Grundy I沒有看到這些問題如何回答這一問題。 – Servy

+0

你是什麼意思在身體的某個地方? 如果您有: 表達式> exStartingPath = x => ExtractStreetData(x.Address); 然後將x.Address轉換爲x.Street或x.Address.Street可能甚至不會生成有效的結構... – MBoros

回答

0

只需抓住lambda的主體,應用成員訪問權限,然後將整個事件包裝回新的lambda。

public static Expression<Func<TSource, TTarget>> ExtendSelection<TSource, TTarget>(
    Expression<Func<TSource, TTarget>> expression, string member) 
{ 
    var body = Expression.PropertyOrField(expression.Body, member); 
    return Expression.Lambda<Func<TSource, TTarget>>(body, expression.Parameters); 
} 
+0

有什麼方法可以使返回類型爲'Expression >而不是'Expression >而不使用'Expression.Convert?正如你可能猜到的,我想將這個表達式傳遞給EF的IQueryable,如果我用Expression.Convert在裏面,我會得到異常說「Linq 2實體只支持鑄造枚舉」。 – user3284063

+0

@ user3284063當然,如果你願意,你可以把'TTarget'的所有實例都改爲'object',但是如果你提供'object'作爲泛型參數,或者提供一個返回'object'的表達式, d做同樣的事情。 – Servy