Build an OR query expression progressively

You would need to construct the filters first, and then combine the filters into a single lambda that you can use as the composed query:

var filters = new List<Expression<Func<YourType, bool>>>();
filters.Add(d => d.TerritoryID == 3);
filters.Add(d => d.CustomerType == "Individual");
...

var lambda = AnyOf(filters.ToArray());
// this is: d => d.TerrotoryID == 3 || d.CustomerType == "Individual";

var data = src.Where(lambda);

Using:

static Expression<Func<T,bool>> AnyOf<T>(
          params Expression<Func<T,bool>>[] expressions)
{
    if (expressions == null || expressions.Length == 0) return x => false;
    if (expressions.Length == 1) return expressions[0];

    var body = expressions[0].Body;
    var param = expressions[0].Parameters.Single();
    for (int i = 1; i < expressions.Length; i++)
    {
        var expr = expressions[i];
        var swappedParam = new SwapVisitor(expr.Parameters.Single(), param)
                            .Visit(expr.Body);
        body = Expression.OrElse(body, swappedParam);
    }
    return Expression.Lambda<Func<T, bool>>(body, param);
}
class SwapVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to){
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

if you want it in two steps, you can use union:

var context = new AdventureWorksDataContext();
// Step 1
var query = context.Customers.Where(d => d.CustomerType == "Individual");
// step2 
query = query.Union(context.Customers.Where(d => d.TerritoryID == 3));


To accomplish what you ask without using the dynamic linq lib, you can define expressions for each test in the where clause, then use them to build a lambda expression:

Expression<Func<Customer, bool>> isIndividualCustomer = c => c.CustomerType == "Individual";

Expression<Func<Customer, bool>> territoryIdIs3 = c => c.TerritoryID == 3;

Expression<Func<Car, bool>> customerIsIndividualOrOfTerritoryId3 = Expression.Lambda<Func<Customer, bool>>(
    Expression.Or(isIndividualCustomer.Body, territoryIdIs3.Body), isIndividualCustomer.Parameters.Single());

Usage:

var query = context.Customers.Where(customerIsIndividualOrOfTerritoryId3);

While you can do this sort of thing directly, I use the LinqKit library which makes such progressive query building really easy:

You would end up with:

var context = new AdventureWorksDataContext();
// Step 1
var query = context.Customers.Where(d => d.CustomerType == "Individual");
// Step 2
query = query.Or(d => d.TerritoryID == 3);

The system I'm working on needs a lot of this, and LinqKit is a major life saver. You can find it here.

(Note: I'm not affiliated with LinqKit's developer in anyway - just a fan.)


Comments

  1. Berisha

    • 2016/2/23

    Can one build a LINQ query to yield an equivalent SQL statement, progressively , such that the resulting query has a WHERE clause with the 

  2. Rhys

    • 2019/4/1

    c# - Build an OR query expression progressively - Stack Overflow. In LINQ one can build a LINQ query progressively as follows:var context = new AdventureWorksDataContext();// Step 1var query = context.Customers.Where(d =&gt; d.CustomerType == "Individual");/ Stack Overflow.

  3. Lochlan

    • 2020/6/10

    Learn to build an expression · Calculate values for controls in forms and reports · Create a calculated field in a query · Set default values for a table field.

  4. Reuben

    • 2018/8/23

    Then, enter the criteria for your expression after the colon. To create your expression by using the Expression Builder, on the ribbon, click Design, and then in the Query Setup group, click Builder. Top of Page. Create a calculated field in a table. In Access, you can create a calculated field in a table.

  5. Reed

    • 2017/8/25

    The function returns a Query value representing the query and it builds the result gradually as it (recursively) walks over the query. The For 

  6. Jacoby

    • 2015/1/15

    If you want to master Language Integrated Query (LINQ), you first need to understand the expressions it is based on. This blog post demonstrates how to dynamically build a LINQ expression tree with multiple nested conditions, use the compiled query to filter an in-memory list, then reuse the expression query a relational database.

  7. Robert

    • 2017/12/1

    Don't be too eager to select too many fields at first, add them gradually to see how they will impact your query; Always check to make sure your table makes 

  8. Morelli

    • 2021/5/16

    Building a query expression. Query expressions are used in ArcGIS to select a subset of features and table records. Query expressions in ArcGIS adhere to standard SQL expressions. For example, you use this syntax using the Select By Attributes tool or with the Query Builder dialog box to set a layer definition query.

  9. Dax

    • 2016/7/29

    Advanced functions can be built into an expression will require another document beyond the scope of this document. This tab is discussed 

  10. Ashton

    • 2020/10/1

    To date, I have been using linq expressions to build up the where predicate using Expression.And & Expression.Or. I want to be able to pass in a string array of column names and progressively build up a linq expression - selector parameter - that I can then pass in to the .Select<> () method. Ultimately, I want an anonymous type from the entire

  11. Eddie

    • 2021/2/11

    LINQ to SQL (Language Integrated Query This way we can apply filters to the data gradually building the expression tree and only then 

  12. Scott

    • 2018/1/16

    To create a query that shows this interval, you need to compare each order date to other order dates for that product. Comparing these order dates also requires a query. You can nest this query inside of your main query by using a subquery. You can write a subquery in an expression or in a Structured Query Language (SQL) statement in SQL view.

  13. Thomas

    • 2015/8/3

    And query building is not a complex task, so the application Changing it to an expression by a query builder later is still possible.

  14. Miller

    • 2019/2/14

    queries that involve multiple query criteria using two or more query expressions. After entering the first complete selection expression, press the AND or OR pushbutton above the ex-pression pane to insert the desired conditional operator. This action also clears the controls above so that you can enter the next expression for the compound query.

  15. Graysen

    • 2017/8/31

    After you build a query, you can execute the query as if you had written it as Columns in SQL queries are sometimes expressions, not simply column names 

  16. Fiore

    • 2017/8/4

    Learn about query syntax and how to construct a search. keyword expression | operator 1 | operator 2 | operator 3.

  17. Ryder

    • 2015/8/31

    Progressive Query Building At the start of the chapter, we demonstrated how or layering of decorators that you would get from a single-expression query.

Comments are closed.

Recent Posts