Expression.Lambda и генерация запросов во время выполнения, простейший пример Where

Я безуспешно пытался сгенерировать простое лямбда-выражение во время выполнения... что-то вроде этого:

var result = queryableData.Where(item => item.Name == "Soap")

Вот мой примерный класс и запрашиваемое приспособление:

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}

IQueryable<Item> queryableData = ...;

Затем я генерирую лямбда-выражение во время выполнения следует правильный код:

//"item" in "item =>..."
var item = Expression
    .Parameter(typeof(Item), "item");

//property of my item, this is "item.Name"
var prop = Expression
    .Property(item, "Name");

//then "Soap" in '... => item.Name=="Soap"'
var value = Expression.Constant("Soap");

//equality expression "==" in my primer
var equals = Expression.Equal(prop, value);

//then lambda
var lambda = Expression.Lambda<Func<Item, bool>>(equals, item);

//and here are the results    
var results = queryableData.Where(lambda);

Большое спасибо dtb за совет!


person CodeAddicted    schedule 29.11.2011    source источник
comment
Вот расширенный пример с вложенным свойством: stackoverflow.com/questions/34270207/   -  person Piotr Czarnecki    schedule 14.12.2015


Ответы (1)


В следующем запросе

var result = query.Where(item => item.Name == "Soap")

лямбда-выражение

item => item.Name == "Soap"

Вам нужно построить только эту часть, а не вызов Where, который принимает дерево выражений.

Дерево выражения для лямбда-выражения выглядит так:

                     Lambda
                      /  \
                   Equal  Parameter
                   /   \    item
              Property  \
               "Name"   Constant
                 |       "Soap"
             Parameter         
               item

В коде:

var item = Expression.Parameter(typeof(Item), "item");

var prop = Expression.Property(item, "Name");

var soap = Expression.Constant("Soap");

var equal = Expression.Equal(prop, soap);

var lambda = Expression.Lambda<Func<Item, bool>>(equal, item);

var result = queryableData.Where(lambda);
person dtb    schedule 29.11.2011
comment
Извините, но что-то не совсем понятно. Вот второе выражение: var propId = Expression.Property(item, "Id"); var minId = Expression.Constant(15); var greaterThan = Expression.GreaterThan(propId, minId); Чтобы объединить equal и greaterThan с && в лямбда-выражении, мне нужно var combined = Expression.AndAlso(equal, greaterThan); Я прав? - person CodeAddicted; 29.11.2011
comment
@dtb У меня есть список объектов с такими объектами, как {id = 1, year = "Year1", month = "Jan", val = 100, othval = 100}, мне нужно { id = 1 , Year1 = { Jan = { val = 100, othval = 100} }}, где я не знаю значение year, и я также не знаю month. Можно ли этого добиться в linq? - person Bharadwaj; 10.02.2015