Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7636083
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T07:35:01+00:00 2026-05-31T07:35:01+00:00

I have a Linq Expression, which may be altered depending on certain conditions. An

  • 0

I have a Linq Expression, which may be altered depending on certain conditions. An example of what I would like to do (left blank the bit I am not sure about):

Expression<Func<Project, bool>> filter = (Project p) => p.UserName == "Bob";
if(showArchived)
{
    // update filter to add && p.Archived
}
// query the database when the filter is built
IEnumerable<Project> projects = unitOfWork.ProjectRepository.Get(filter);

How do I update the filter to add any extra parameters?

At the moment all the records are retrieved, then I use a Where to further filter the results. However that results in more queries to the database than are strictly necessary.

IEnumerable<Project> projects = unitOfWork.ProjectRepository.Get(filter);
if(showArchived)
{
    projects = projects.Where(p => p.Archived);
}

Get method is using the GenericRepository pattern:

public class GenericRepository<TEntity> where TEntity : class
{
    internal ProgrammeDBContext context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(ProgrammeDBContext context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual TEntity GetByID(object id)
    {
        return dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entityToDelete)
    {
        if (context.Entry(entityToDelete).State == EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }

    public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        context.Entry(entityToUpdate).State = EntityState.Modified;
    }

    public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
    {
        return dbSet.SqlQuery(query, parameters).ToList();
    }
}

Update
Created some extension methods based on the code below by Marc Gravell and David B, solves the problem for me

public static class LinqExtensionMethods
{
    public static Expression<Func<T, bool>> CombineOr<T>(params Expression<Func<T, bool>>[] filters)
    {
        return filters.CombineOr();
    }

    public static Expression<Func<T, bool>> CombineOr<T>(this IEnumerable<Expression<Func<T, bool>>> filters)
    {
        if (!filters.Any())
        {
            Expression<Func<T, bool>> alwaysTrue = x => true;
            return alwaysTrue;
        }
        Expression<Func<T, bool>> firstFilter = filters.First();

        var lastFilter = firstFilter;
        Expression<Func<T, bool>> result = null;
        foreach (var nextFilter in filters.Skip(1))
        {
            var nextExpression = new ReplaceVisitor(lastFilter.Parameters[0], nextFilter.Parameters[0]).Visit(lastFilter.Body);
            result = Expression.Lambda<Func<T, bool>>(Expression.OrElse(nextExpression, nextFilter.Body), nextFilter.Parameters);
            lastFilter = nextFilter;
        }
        return result;
    }

    public static Expression<Func<T, bool>> CombineAnd<T>(params Expression<Func<T, bool>>[] filters)
    {
        return filters.CombineAnd();
    }

    public static Expression<Func<T, bool>> CombineAnd<T>(this IEnumerable<Expression<Func<T, bool>>> filters)
    {
        if (!filters.Any())
        {
            Expression<Func<T, bool>> alwaysTrue = x => true;
            return alwaysTrue;
        }
        Expression<Func<T, bool>> firstFilter = filters.First();

        var lastFilter = firstFilter;
        Expression<Func<T, bool>> result = null;
        foreach (var nextFilter in filters.Skip(1))
        {
            var nextExpression = new ReplaceVisitor(lastFilter.Parameters[0], nextFilter.Parameters[0]).Visit(lastFilter.Body);
            result = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(nextExpression, nextFilter.Body), nextFilter.Parameters);
            lastFilter = nextFilter;
        }
        return result;
    }

    class ReplaceVisitor : ExpressionVisitor
    {
        private readonly Expression from, to;
        public ReplaceVisitor(Expression from, Expression to)
        {
            this.from = from;
            this.to = to;
        }
        public override Expression Visit(Expression node)
        {
            return node == from ? to : base.Visit(node);
        }
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T07:35:02+00:00Added an answer on May 31, 2026 at 7:35 am

    If I understand the question, then most likely here’s the problem:

    IEnumerable<Project> projects = unitOfWork.ProjectRepository.Get(filter);
    

    Any work on projects is going to be using Enumerable, not Queryable; it should probably be:

    IQueryable<Project> projects = unitOfWork.ProjectRepository.Get(filter);
    if(showArchived)
    {
        projects = projects.Where(p => p.Archived);
    }
    

    The latter is composable, and .Where should work as you expect, building up a more restrictive query before sending it to the server.

    Your other option is to rewrite the filter to combine before sending:

    using System;
    using System.Linq.Expressions;
    
    static class Program
    {
        static void Main()
        {
            Expression<Func<Foo, bool>> filter1 = x => x.A > 1;
            Expression<Func<Foo, bool>> filter2 = x => x.B > 2.5;
    
            // combine two predicates:
            // need to rewrite one of the lambdas, swapping in the parameter from the other
            var rewrittenBody1 = new ReplaceVisitor(
                filter1.Parameters[0], filter2.Parameters[0]).Visit(filter1.Body);
            var newFilter = Expression.Lambda<Func<Foo, bool>>(
                Expression.AndAlso(rewrittenBody1, filter2.Body), filter2.Parameters);
            // newFilter is equivalent to: x => x.A > 1 && x.B > 2.5
        }
    }
    class Foo
    {
        public int A { get; set; }
        public float B { get; set; }
    }
    class ReplaceVisitor : ExpressionVisitor
    {
        private readonly Expression from, to;
        public ReplaceVisitor(Expression from, Expression to)
        {
            this.from = from;
            this.to = to;
        }
        public override Expression Visit(Expression node)
        {
            return node == from ? to : base.Visit(node);
        }
    }
    

    Or re-written in a way to allow convenient usage:

    using System;
    using System.Linq.Expressions;
    
    static class Program
    {
        static void Main()
        {
            Expression<Func<Foo, bool>> filter = x => x.A > 1;
    
            bool applySecondFilter = true;
            if(applySecondFilter)
            {
                filter = Combine(filter, x => x.B > 2.5);
            }
            var data = repo.Get(filter);
        }
        static Expression<Func<T,bool>> Combine<T>(Expression<Func<T,bool>> filter1, Expression<Func<T,bool>> filter2)
        {
            // combine two predicates:
            // need to rewrite one of the lambdas, swapping in the parameter from the other
            var rewrittenBody1 = new ReplaceVisitor(
                filter1.Parameters[0], filter2.Parameters[0]).Visit(filter1.Body);
            var newFilter = Expression.Lambda<Func<T, bool>>(
                Expression.AndAlso(rewrittenBody1, filter2.Body), filter2.Parameters);
            return newFilter;
        }
    }
    class Foo
    {
        public int A { get; set; }
        public float B { get; set; }
    }
    class ReplaceVisitor : ExpressionVisitor
    {
        private readonly Expression from, to;
        public ReplaceVisitor(Expression from, Expression to)
        {
            this.from = from;
            this.to = to;
        }
        public override Expression Visit(Expression node)
        {
            return node == from ? to : base.Visit(node);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a GridView what I fill through a LINQ expression. Something like this:
I have two LINQ objects which have exactly the same columns and I would
I have a method which have this signature public static IList<T> GetBy<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression)
I want a Linq Expression which dynamically compiles at runtime I have a value
I have a Linq expression that operates on a list of objects for which
I have a function which creates a different type of expression depending on the
I currently have code which produces the following LINQ expression (taken from the WhoCanHelpMe
I have the following LINQ expression that's not returning the appropriate response var query
I have a DataGridView bound to a LINQ to SQL query expression. I want
I have LINQ statement that looks like this: return ( from c in customers

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.