Linq исключение для Provider.CreateQuery - PullRequest
0 голосов
/ 11 февраля 2019

Для данного класса:

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

Следующий список:

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();

И этот код, в котором я пытаюсь динамически запрашивать список (обратите внимание, что строка query может содержатьчто-нибудь типа Take, Select, OrderBy и т. д.).

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();

Я хочу знать, что я делаю неправильно, что выражение Provider.CreateQuery thowing выражено недопустимым"исключение?

1 Ответ

0 голосов
/ 11 февраля 2019

Разница с DynamicExpression.Parse (отсюда и причина проблемы) заключается в том, что метод DynamicExpressionParser.ParseLambda возвращает LambdaExpression (в основном Expression<Func<TResult>>), который не является допустимым выражением запроса.

Но Body этого есть, поэтому самое простое решение - использовать

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

В качестве альтернативы вы можете использовать класс System.Linq.Dynamic.Core.Parser.ExpressionParser напрямую:

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