Expression.Lambda and query generation at runtime, simplest "Where" example

29,345

In the following query

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

the lambda expression is

item => item.Name == "Soap"

You only need to construct this part, not the Where call which accepts an expression tree.

The expression tree for the lambda expression looks like this:

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

In code:

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);
Share:
29,345
CodeAddicted
Author by

CodeAddicted

Updated on October 12, 2020

Comments

  • CodeAddicted
    CodeAddicted over 3 years

    I was trying to generate a simple Lambda Expression at runtime with no luck... something like this:

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

    Here is my example class and a fixture queryable:

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    IQueryable<Item> queryableData = ...;
    

    Then I generate a lambda expression at runtime correct code follows:

    //"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);
    

    Big thanks to dtb for advice!

  • CodeAddicted
    CodeAddicted over 12 years
    Sorry, but something is not clear enough. Here is a second expression: var propId = Expression.Property(item, "Id"); var minId = Expression.Constant(15); var greaterThan = Expression.GreaterThan(propId, minId); To combine equal and greaterThan with && in lambda I need var combined = Expression.AndAlso(equal, greaterThan); Am I right?
  • Bharadwaj
    Bharadwaj about 9 years
    @dtb I have object list with object in it like {id = 1, year = "Year1", month = "Jan", val = 100, othval = 100}, what I need is { id = 1 , Year1 = { Jan = { val = 100, othval = 100} }}, where I don't know the year value and I don't know month also. Can this be achieved in linq?