Получите доступ к значению членского выражения

Если у меня есть продукт.

var p = new Product { Price = 30 };

и у меня есть следующий запрос linq.

var q = repo.Products().Where(x=>x.Price == p.Price).ToList()

В поставщике IQueryable я возвращаю MemberExpression для p. Цена, которая содержит Константное выражение, однако я, может казаться, не получаю значение "30" назад от него.

Обновление я попробовал это, но это, кажется, не работает.

var memberExpression = (MemberExpression)GetRootConstantExpression(m);
var fi = (PropertyInfo)memberExpression.Member;
var val = fi.GetValue(((ConstantExpression)memberExpression.Expression).Value, null);

Удачи.

63
задан Schotime 11 April 2010 в 12:10
поделиться

5 ответов

Вы можете скомпилировать и вызвать лямбда-выражение, телом которого является доступ к члену:

private object GetValue(MemberExpression member)
{
    var objectMember = Expression.Convert(member, typeof(object));

    var getterLambda = Expression.Lambda<Func<object>>(objectMember);

    var getter = getterLambda.Compile();

    return getter();
}

Локальная оценка - распространенный метод при синтаксическом анализе деревьев выражений. LINQ to SQL делает именно это во многих местах.

102
ответ дан 24 November 2019 в 16:11
поделиться

q имеет тип List . В списке нет свойства Price - только отдельные продукты.

У первого или последнего Продукта будет цена.

q.First().Price
q.Last().Price

Если вы знаете, что в коллекции только один, вы также можете сгладить его с помощью Single

q.Single().Price
1
ответ дан 24 November 2019 в 16:11
поделиться

Постоянное выражение будет указывать на класс захвата, сгенерированный компилятором. Я не включил точки принятия решения и т. Д., Но вот как получить 30 из этого:

var p = new Product { Price = 30 };
Expression<Func<Product, bool>> predicate = x => x.Price == p.Price;
BinaryExpression eq = (BinaryExpression)predicate.Body;
MemberExpression productToPrice = (MemberExpression)eq.Right;
MemberExpression captureToProduct = (MemberExpression)productToPrice.Expression;
ConstantExpression captureConst = (ConstantExpression)captureToProduct.Expression;
object product = ((FieldInfo)captureToProduct.Member).GetValue(captureConst.Value);
object price = ((PropertyInfo)productToPrice.Member).GetValue(product, null);

цена теперь 30 . Обратите внимание, что я предполагаю, что Price является свойством, но на самом деле вы должны написать метод GetValue , который обрабатывает свойство / поле.

24
ответ дан 24 November 2019 в 16:11
поделиться

Можете ли вы использовать следующее:

var price = p.Price;
var q = repo.Products().Where(x=>x.Price == price).ToList()
1
ответ дан 24 November 2019 в 16:11
поделиться

А чего именно вы пытаетесь достичь?

Поскольку для доступа к значению Price вам нужно будет сделать что-то вроде:

var valueOfPrice = q[0].Price;
0
ответ дан 24 November 2019 в 16:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: