Linq exception on Provider.CreateQuery

1.7k Views Asked by At

Given this class:

class SomeClass
{
    public int SomeValue { get; set; }
}

The following list:

var queryableData = new List<SomeClass>() {
    new SomeClass{SomeValue=1 },
    new SomeClass{SomeValue=2 },
    new SomeClass{SomeValue=3 },
    new SomeClass{SomeValue=4 },
    new SomeClass{SomeValue=5 },
    new SomeClass{SomeValue=6 },
    new SomeClass{SomeValue=7 },
}.AsQueryable();

And this code where i try to dinamically query the list (note that the string query could contain anything such as Take,Select,OrderBy, etc).

var externals = new Dictionary<string, object>();
externals.Add("SomeClass", queryableData);

string query = "SomeClass.Where(o => o.SomeValue >= 3)"; // or any query

// here i use the code from System.Linq.Dynamic
var expression = DynamicExpression.Parse(typeof(IQueryable<SomeClass>), query, new[] { externals });
// result will have five values
var result = queryableData.Provider.CreateQuery<SomeClass>(expression);

// here i use the code from System.Linq.Dynamic.Core
var expression2 = DynamicExpressionParser.ParseLambda(typeof(IQueryable<SomeClass>), query, new[] { externals });
// will throw exception here: Argument expression is not valid
var result2 = queryableData.Provider.CreateQuery<SomeClass>(expression2).ToDynamicArray();

I want to know what am i doing wrong that the Provider.CreateQuery is thowing the "Argument expression is not valid" exception?

1

There are 1 best solutions below

0
On BEST ANSWER

The difference with DynamicExpression.Parse (hence the cause of the problem) is that the DynamicExpressionParser.ParseLambda method returns LambdaExpression (basically Expression<Func<TResult>>) which is not a valid query expression.

But the Body of it is, so the simplest fix is to use

var result2 = queryableData.Provider.CreateQuery<SomeClass>(expression2.Body);

Alternatively you could use System.Linq.Dynamic.Core.Parser.ExpressionParser class directly:

var expression2 = new ExpressionParser(null, query, new[] { externals }, null)
    .Parse(typeof(IQueryable<SomeClass>));
var result2 = queryableData.Provider.CreateQuery<SomeClass>(expression2);