Если у меня есть продукт.
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);
Удачи.
Вы можете скомпилировать и вызвать лямбда-выражение, телом которого является доступ к члену:
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 делает именно это во многих местах.
q
имеет тип List
. В списке нет свойства Price - только отдельные продукты.
У первого или последнего Продукта будет цена.
q.First().Price
q.Last().Price
Если вы знаете, что в коллекции только один, вы также можете сгладить его с помощью Single
q.Single().Price
Постоянное выражение будет указывать на класс захвата, сгенерированный компилятором. Я не включил точки принятия решения и т. Д., Но вот как получить 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
, который обрабатывает свойство / поле.
Можете ли вы использовать следующее:
var price = p.Price;
var q = repo.Products().Where(x=>x.Price == price).ToList()
А чего именно вы пытаетесь достичь?
Поскольку для доступа к значению Price
вам нужно будет сделать что-то вроде:
var valueOfPrice = q[0].Price;