using System.Linq.Expressions;
using System.Collections.Generic;
public static void Main()
var list = new List<Person>
Expression<Func<Person, bool>> filterName = GetFilterName();
Expression<Func<Person, bool>> filterAge = GetFilterAge();
Expression<Func<Person, bool>> expresion = EFCoreExpressionTreeHelper.AndExpression(filterName, filterAge);
Func<Person, bool> predicate = expresion.Compile();
var result = list.Where(predicate);
Console.WriteLine(result.FirstOrDefault()?.Name);
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
static Expression<Func<Person, bool>> GetFilterName()
return x => x.Name.StartsWith("T");
static Expression<Func<Person, bool>> GetFilterAge()
public static class EFCoreExpressionTreeHelper
public static Expression<Func<T, bool>> AndExpression<T>(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
var visitor = new ParameterReplaceVisitor(right.Parameters[0], left.Parameters[0]);
var rewrittenRight = visitor.Visit(right.Body);
var andExpression = Expression.AndAlso(left.Body, rewrittenRight);
return Expression.Lambda<Func<T, bool>>(andExpression, left.Parameters);
private class ParameterReplaceVisitor : ExpressionVisitor
public ParameterReplaceVisitor(ParameterExpression target, ParameterExpression replacement)
Replacement = replacement;
public ParameterExpression Target { get; private set; }
public ParameterExpression Replacement { get; private set; }
protected override Expression VisitParameter(ParameterExpression node)
return node == Target ? Replacement : base.VisitParameter(node);