Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

LINQ Extensions - C#

RSS
Modified on Fri, May 06, 2022, 9:21 AM by Administrator Categorized as Uncategorized

Overview

This article provides the code for two extension methods for use when building expressions, commonly used with LINQ. These functions allow you to build Boolean expressions on the fly.

  • OrElse()
  • AndAlso()

Sample Usage

The CustomerOrder is only used as an example; it can be any class.

Expression<Func<CustomerOrder, bool>> expr = x => false;

if (someCondition)
{
    expr = expr.OrElse(a => a.OrderAmount >= 1000);
}

if (someOtherCondition)
{
    expr = expr.OrElse(a => a.OrderAmount <= 5000);
}

var items = _db.CustomerOrders.Where(expr.AndAlso(a => !a.IsDeleted));

Extension Methods

using System;
using System.Linq.Expressions;

public static class LinqExtensions
{
    /* Adapted from
        * https://stackoverflow.com/questions/29565373/combine-listexpressionfunct-bool-to-an-or-clause-linq
        */
    public static Expression<Func<T, bool>> OrElse<T>(
        this Expression<Func<T, bool>> a,
        Expression<Func<T, bool>> b)
    {
        var bodyB = b.Body.Replace(b.Parameters[0], a.Parameters[0]);

        return Expression.Lambda<Func<T, bool>>(Expression.OrElse(a.Body, bodyB), a.Parameters);
    }


    public static Expression<Func<T, bool>> AndAlso<T>(
        this Expression<Func<T, bool>> a,
        Expression<Func<T, bool>> b)
    {
        var bodyB = b.Body.Replace(b.Parameters[0], a.Parameters[0]);

        return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(a.Body, bodyB), a.Parameters);
    }


    private static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx)
    {
        return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
    }


    private class ReplaceVisitor : ExpressionVisitor
    {
        private readonly Expression _from, _to;
        public ReplaceVisitor(Expression from, Expression to)
        {
            _from = from;
            _to = to;
        }
        public override Expression Visit(Expression node)
        {
            return node == _from ? _to : base.Visit(node);
        }
    }
}

ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.