2012-01-09 44 views
1

如何achive相同的結果:如何添加的SelectMany一個表達式樹Expression.Call

var q = db.TableA.AsQueryable(); 
var q1 = Queryable.SelectMany(q, a => a.TableB, (a, t) => new { a = a, t = t }); 
var q2 = Queryable.SelectMany(q1, a=> a.a.TableC, (a, t) = new { a = a, t = t }); 

經由Expression.Call創建一個表達式樹:

MethodCallExpression returnCallExpression = Expression.Call(
    typeof(Queryable), 
    "SelectMany", 
    new Type[] ??????, 
    query.Expression, 
    a => a.TableB, 
    (a, t) => new { a = a, t = t }); 

我在調查Expression.Call的其他重載,看看這是否可以在沒有聲明類型的情況下實現。

我的問題是SelectManys的數量是在運行時確定的,所以我不能鏈接它們。並且每個SelectMany都會更改IQueryable的匿名類型,所以我在編譯時無法獲知該類型。

有關如何將n個SelectMany應用於IQueryable的任何想法都非常感謝。

回答

1

你確實有lambda表達式「可用」,如a => a.TableB還是它們是動態的嗎?

你可以使用這樣的事情也許是(在此基礎上SO post):

public Type[] GetSelectManysAnonymousTypes<TSource, TCollection, TResult>(
     IQueryable<TSource> queryable, 
     Expression<Func<TSource, IEnumerable<TCollection>>> collectionSelector, 
     Expression<Func<TSource, TCollection, TResult>> resultSelector) 
{ 
    return new [] { 
     typeof(Expression<Func<TSource, IEnumerable<TCollection>>>), 
     typeof(Expression<Func<TSource, TCollection, TResult>>) }; 
} 

或者一些更復雜的可以一起退給你Type[]與表達的Expression[]即陣列 - 準備打電話表達。呼叫()。

我認爲你面臨的問題是,忘記匿名類型,如果你真的有一個動態的,未知數量的SelectMany()鏈接在一起,你不知道collectionSelector參數lambda看起來像什麼。或者我可能會錯過一些東西...