Dynamic Expression

2 posts, 0 answers
  1. devoas
    devoas avatar
    69 posts
    Member since:
    Dec 2009

    Posted 20 Jan 2010 Link to this post


    Please guide the recommended way to join Dynamic expressions. Basically we have different selection criterias
    [ ] By Transaction ID:  ________        (.) And    ( ) Or
    [ ] By Customer ID : __________        (.) And    ( ) Or
    [ ] By Date : _________                      (.) And    ( ) Or

    for this we prepare different Dynamic expressions based on user selection like following.




    Expression <Func<SalesMaster, bool>predicatex = c=>c.TranNumb ==2;   
    Expression<Func<SalesMaster, bool>predicatey = c=>c.CustomerId ==2;  


    Now Please recommend how can I Join multiple predicates based on AND/OR operation and apply in single Where Cluase

    currently we are using following approach...

    var query = from p in scope.Extent<SalesMaster>().Where(predicatex)   
                      select p;  
    query = query.Where(predicatex);  
    query = query.Where(predicatey);  
    var result = query.ToList();  

    But this approach does allow us to use OR  all these clauses generate AND

    I tried to join predicates using Expression.And and Expression.Or  but resultant predicate is compile and throwing exception as posted previously.

    Please Help...

  2. Jordan
    Jordan avatar
    547 posts

    Posted 22 Jan 2010 Link to this post

    Hi devoas,

    You can easily combine multiple lambda expressions with the code bellow:
    Expression<Func<Customer, bool>> filter1 = c => c.City.StartsWith("S");
    Expression<Func<Customer, bool>> filter2 = c => c.City.StartsWith("M");
    Expression<Func<Customer, bool>> filter3 = c => c.ContactTitle == "Owner";
    Expression<Func<Customer, bool>>[] filterExpressions = new Expression<Func<Customer, bool>>[] { filter1, filter2, filter3 };
    Func<Expression, Expression, BinaryExpression>[] operators = new Func<Expression, Expression, BinaryExpression>[] { Expression.OrElse , Expression.AndAlso};
    Expression<Func<Customer, bool>> filter = null;
    if (filterExpressions.Length > 0)
        Expression body = filter1.Body;
        for (int i = 1; i < filterExpressions.Length; i++)
            body = operators[i - 1](body, filterExpressions[i].Body);
        filter = Expression.Lambda<Func<Customer, bool>>(body, filter1.Parameters);
    IObjectScope objectScope = ObjectScopeProvider1.GetNewObjectScope();
    IQueryable<Customer> query = (from c in objectScope.Extent<Customer>() select c).Where(filter);
    Notice that the Expression methods used are OrElse and AndAlso. They produce binary expressions.
    The And and Or methods produce bitwise operations.

    The result lambda expression will look like this:
    filter = {c => ((c.City.StartsWith("S") || c.City.StartsWith("M")) && (c.ContactTitle = "Owner"))}

    And the generated SQL will look like this:
    "SELECT [CustomerID] AS COL1, [Address] AS COL2, [City] AS COL3, [CompanyName] AS COL4, [ContactName] AS COL5, [ContactTitle] AS COL6, [Country] AS COL7, [Fax] AS COL8, [Phone] AS COL9, [PostalCode] AS COL10, [Region] AS COL11 FROM [Customers] WHERE ([City] LIKE 'S%' OR [City] LIKE 'M%') AND [ContactTitle] = 'Owner' "

    I hope this helps.
    Do not hesitate to write again if you have more questions or suggestions.

    Best wishes,
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. DevCraft banner
Back to Top