Question

I'm trying to implement the SelectMany statement inside of the dynamic linq expresion parser, such that I could run a query like so:

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

Such that it would be equivilent to the linq query:

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

I've tried adding SelectMany to the IEnumerableSignatures of System.Linq.Dynamic.ExpressionParser, but it looks like there's more I need to do.

I've looked into this codeplex project but didn't get anywhere with it: http://dynamiclinq.codeplex.com/ specificaly it wouldn't run my old queries and didn't have support for select or select many.

Ultimately I'd like to use all of the ienumerable linq statements inside of a dynamic linq statement.

Was it helpful?

Solution

For make SelectMany work inside dynamic linq queries you shoud not only modify IEnumerableSignatures, but also change ParseAggregate method to pass specific typeArgs for SelectMany, in this way:

    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 };
        }
        ...
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top