如何实现外连接表达式树? [英] How to implement outer join expression tree?

查看:144
本文介绍了如何实现外连接表达式树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用表达式语法来实现查询(因为我在编译时不知道类型)。例如,如下所示的查询:

I need to implement the query using expressions syntax (because I don't know types in compile time). For example query like this one:

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 }

我找到了实现组合加入部分的方法:

I found way to implement group join part like this:

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

但是我不知道如何使用这种语法写出其余的查询。
有人可以帮助我吗?

But I can't figure out how to write rest of query using this syntax. Does anyone can help me?

推荐答案

我刚刚复制+粘贴了dynamic.cs中的join做了几个变化,使GroupJoin工作。

I just copied + pasted the "join" implementation in dynamic.cs and made couple of changes to make "GroupJoin" to work.

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

这篇关于如何实现外连接表达式树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆