2009-05-22 11 views
0

Ich muss die Abfrage mit Ausdruckssyntax implementieren (weil ich Typen in Kompilierzeit nicht kenne). Zum Beispiel Abfrage wie diese:Wie implementiert man den äußeren Join-Ausdrucksbaum?

from customer in Customers 
join purchase in Purchases 
    on customer.ID equals purchase.CustomerID 
into outerJoin 
from range in outerJoin.DefaultIfEmpty() 
where 
    customer.Name == "SomeName" && 
    range.Description.Contains("SomeString") && 
    customer.ID == range.CustomerID 
select 
    new { Customer = customer, Purchase = range } 

fand ich Art und Weise Gruppe mitmachen Teil wie folgt umzusetzen:

ITable p = _dataContext.GetTable(typeof(Purchases)); 
ITable c = _dataContext.GetTable(typeof(Customers)); 

LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(typeof(Customers), null, "ID"); 
LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(typeof(Purchases), null, "CustomerID"); 

ParameterExpression param1 = Expression.Parameter(typeof(Customers), "customer"); 
ParameterExpression param2 = Expression.Parameter(typeof(IEnumerable<Purchases>), "purchases"); 

ParameterExpression[] parameters = new ParameterExpression[] { param1, param2 }; 

LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, "New(customers as customers, purchases as purchases)"); 

MethodCallExpression joinCall = 
Expression.Call(
    typeof(Queryable), 
    "GroupJoin", 
    new Type[] { 
     typeof(Customers), 
     typeof(Purchases), 
     outerSelectorLambda.Body.Type, 
     resultsSelectorLambda.Body.Type 
    }, 
    c.Expression, 
    p.Expression, 
    Expression.Quote(outerSelectorLambda), 
    Expression.Quote(innerSelectorLambda), 
    Expression.Quote(resultsSelectorLambda) 
); 

Aber ich kann nicht herausfinden, wie Rest der Abfrage zu schreiben, um diese Syntax . Kann mir jemand helfen?

Antwort

0

Ich habe einfach die "Join" -Implementierung in dynamic.cs kopiert und eingefügt und einige Änderungen vorgenommen, damit "GroupJoin" funktioniert.

public static IQueryable GroupJoin(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) 
{ 
    if (inner == null) throw new ArgumentNullException("inner"); 
    if (outerSelector == null) throw new ArgumentNullException("outerSelector"); 
    if (innerSelector == null) throw new ArgumentNullException("innerSelector"); 
    if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor"); 

    LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values); 
    LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values); 

    Type resultType = typeof(IEnumerable<>).MakeGenericType(inner.AsQueryable().ElementType); 

    ParameterExpression[] parameters = new ParameterExpression[] 
    { 
     Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(resultType, "inner") 
    }; 
    LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values); 

    return outer.Provider.CreateQuery(
       Expression.Call(
        typeof(Queryable), "GroupJoin", 
        new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type }, 
        outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda))); 
} 
0

würde ich einen Ansatz folgen, das zu erreichen:

  1. die Expression Äquivalent der Abfrage LINQ Get.

  2. Ruft den ToString() des aus der LINQ-Abfrage extrahierten Ausdrucks ab.

  3. Studie der Expression, die Eingangsparameter zu verstehen, Typ Parameter, Expression Argumente etc ...

zu mir zurück, wenn der erwähnte Ansatz ist nicht klar.

Verwandte Themen