【问题标题】:How to implement SelectMany in System.Linq.Dynamic ExpressionParser如何在 System.Linq.Dynamic ExpressionParser 中实现 SelectMany
【发布时间】:2013-11-28 15:11:47
【问题描述】:

我正在尝试在动态 linq 表达式解析器中实现 SelectMany 语句,这样我就可以像这样运行查询:

Customers.Select("Orders.SelectMany(OrderItems)")

这样它就等同于 linq 查询:

Customers.Select(cust => cust.Orders.SelectMany(ord => ord.OrderItems))

我已尝试将 SelectMany 添加到 System.Linq.Dynamic.ExpressionParser 的 IEnumerableSignatures,但看起来我还需要做更多工作。

我研究了这个 codeplex 项目,但没有得到任何结果:http://dynamiclinq.codeplex.com/ 特别是它不会运行我的旧查询并且不支持 select 或 select many。

最终我想在动态 linq 语句中使用所有可枚举的 linq 语句。

【问题讨论】:

    标签: c# dynamic-linq linq


    【解决方案1】:

    为了使 SelectMany 在动态 linq 查询中工作,您不仅应该修改 IEnumerableSignatures,还应该更改 ParseAggregate 方法以将特定的 typeArgs 传递给 SelectMany,这样:

        Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
        {
            ...
            Type[] typeArgs;
            if (signature.Name == "Min" || signature.Name == "Max")
            {
                typeArgs = new Type[] { elementType, args[0].Type };
            }
            else if(signature.Name == "Select")
            {
                typeArgs = new Type[] { elementType, Expression.Lambda(args[0], innerIt).Body.Type };
            } 
            else if(signature.Name == "SelectMany")
            {
                var type = Expression.Lambda(args[0], innerIt).Body.Type;
                var interfaces = type.GetInterfaces().Union(new[] { type });
                Type resultType = interfaces.Single(a => a.Name == typeof(IEnumerable<>).Name).GetGenericArguments()[0];
                typeArgs = new Type[] { elementType, resultType };
            }
            else
            {
                typeArgs = new Type[] { elementType };
            }
            ...
        }
    

    【讨论】:

    • 谢谢,完美运行,我还注意到您也添加了 Select。请注意,我必须确保 SelectMany 签名包含对象选择器,即 void SelectMany(object selector)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多