Linq исключение для Provider.CreateQuery
Учитывая этот класс:
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
является ли исключение "выражение аргумента недействительным"?
1 ответ
Разница с DynamicExpression.Parse
(следовательно, причина проблемы) заключается в том, что DynamicExpressionParser.ParseLambda
метод возвращает LambdaExpression (в основном Expression<Func<TResult>>
), который не является допустимым выражением запроса.
Но Тело это так, поэтому самое простое решение заключается в использовании
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);