Расширение выражений LINQ - PullRequest
2 голосов
/ 29 апреля 2019

Вопрос новичка LINQ Expressions-

Expression<Func<TLookupModel, TValue>> idSelector;
IEnumerable<TLookupModel> source;
TValue id;

Я пытаюсь сделать (псевдокод):

source.AsQueryable().FirstOrDefault(x => idSelector == id)

Моя слабая попытка до сих пор:

var expressionParam = idSelector.Parameters.First();

ConstantExpression selectedValueConstant = Expression.Constant(id, typeof(TValue));

var idEqualExpression = Expression.Equal(idSelector, selectedValueConstant);

var lambda = Expression.Lambda<Func<TLookupModel, bool>>(idEqualExpression, expressionParam);

var selectedSourceItem = source.AsQueryable().FirstOrDefault(lambda);

Я думаю, это дает вам предположение о том, как я до сих пор думал. Я пробовал с параметрами и без параметров, различные комбинации вызовов методов Expression, пытаясь получить «параметр» из вызова FirstOrDefault(), но после прочтения большого количества руководств я не могу понять, как расширить выражение-член, равное константе таким образом.

1 Ответ

2 голосов
/ 29 апреля 2019

Ты действительно близко.

Ваше idExpression является выражением в виде x => x.Property. Однако вы передаете все выражение в выражение Equal. Измените это, чтобы передать только тело:

var idEqualExpression = Expression.Equal(idSelector.Body, selectedValueConstant);

Затем вы можете скомпилировать лямбду и передать ее в FirstOrDefault без приведения к запросу:

var selectedSourceItem = source.FirstOrDefault(lambda.Compile());
...