我正在尝试在动态linq expresion解析器中实现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语句。
答案 0 :(得分:3)
对于make SelectMany在动态linq查询中的工作,你不仅要修改IEnumerableSignatures,还要更改ParseAggregate方法,以便为SelectMany传递特定的typeArgs,这样:
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 };
}
...
}