如何创建动态LINQ join扩展方法 [英] How to create a dynamic LINQ join extension method

查看:27
本文介绍了如何创建动态LINQ join扩展方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个动态 LINQ 扩展方法库作为示例发布,Visual Studio 2008.我想用 join 方法扩展它.下面的代码在运行时因参数未命中匹配异常而失败.问题出在哪里?

There was a library of dynamic LINQ extensions methods released as a sample with Visual Studio 2008. I'd like to extend it with a join method. The code below fails with a parameter miss match exception at run time. Where is the problem?

public static IQueryable Join(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);

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

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

推荐答案

我现在自己解决了.这是一个向 CreateQuery(... ) 调用传递太多参数的小学生错误.将以下代码粘贴到 DynamicQueryable 类中的 Dynamic.cs 文件中,以获取动态 Join 扩展方法.您可以在 http://code.msdn.microsoft.com/csharpsamples<上找到 DynamicQuery 示例项目的源代码/a>.
享受吧.

I've fixed it myself now. It was a schoolboy error passing too many parameters to the CreateQuery(... ) call. Paste the following code into the Dynamic.cs file within the DynamicQueryable class for a dynamic Join extension method. You can find the source for the DynamicQuery sample project at http://code.msdn.microsoft.com/csharpsamples.
Enjoy.

    public static IQueryable Join(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);

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

        return outer.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Join",
                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)));
    }


    //The generic overload.
    public static IQueryable<T> Join<T>(this IQueryable<T> outer, IEnumerable<T> inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values)
    {
        return (IQueryable<T>)Join((IQueryable)outer, (IEnumerable)inner, outerSelector, innerSelector, resultsSelector, values);
    }

这篇关于如何创建动态LINQ join扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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