2009-05-22 9 views
0

J'ai besoin d'implémenter la requête en utilisant la syntaxe des expressions (parce que je ne connais pas les types à la compilation). Par exemple requête comme celle-ci:Comment implémenter l'arborescence d'expression de jointure externe?

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 } 

J'ai trouvé moyen de mettre en œuvre un groupe se joindre à une partie comme ceci:

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) 
); 

Mais je ne peux pas comprendre comment écrire reste de requête en utilisant cette syntaxe . Est-ce que quelqu'un peut m'aider?

Répondre

0

Je viens de copier + coller l'implémentation "join" dans dynamic.cs et j'ai fait quelques changements pour que "GroupJoin" fonctionne.

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

je suivrais une approche pour y parvenir:

  1. Obtenez l'expression équivalente de la requête LINQ.

  2. Obtient le ToString() de l'expression extraite de la requête LINQ.

  3. étudier l'expression, pour comprendre les paramètres d'entrée, les paramètres de type, expression Arguments etc ...

Revenez à moi si l'approche mentionnée est pas claire.

Questions connexes