Chaining multiple predicates
To answer the direct question, the obvious way is to have an All method which takes a params Expression&lt;Func&lt;T, bool&gt;&gt;[] expressions argument. You'll still have a 30-line call, but you won't have And on each line. There are potential side-benefits:


It should reduce the amount of wrapping an expression just to unwrap it immediately.
If you decide that you want AndAlso instead of And (is there any reason for not using it?) then it's much simpler to change.




I would also be tempted to favour a refactor which allows null expressions. If instead of


public Expression&lt;Func&lt;Project, bool&gt;&gt; GetProjectByProjectId()
{
    return prj =&gt; FilterCriteria.ProjectId == null || prj.ProjectID == FilterCriteria.ProjectId.Value;
}



you have

public Expression&lt;Func&lt;Project, bool&gt;&gt; GetProjectByProjectId()
{
    return FilterCriteria.ProjectId == null ? null : (prj =&gt; prj.ProjectID == FilterCriteria.ProjectId.Value);
}


(with whatever type coercion is necessary to make that compile - I haven't tested it) then you can filter out null expressions in All. This both simplifies the expression constructed and the SQL generated from it, which might improve performance and might also make debugging it easier.



Finally, two comments about SubstExpressionVisitor:


    public Dictionary&lt;Expression, Expression&gt; subst = new Dictionary&lt;Expression, Expression&gt;();



On the basis of coding to the interface rather than the implementation, the type should be IDictionary&lt;Expression, Expression&gt;. I personally would also prefer to hide the field and take the substitutions as arguments to the constructor rather than by modifying a public field after construction, but that's a subjective issue of style. If making that change, the type can become IReadOnlyDictionary&lt;Expression, Expression&gt; instead.


    protected override Expression VisitParameter(ParameterExpression node)
    {
        Expression newValue;
        if (subst.TryGetValue(node, out newValue))
        {
            return newValue;
        }
        return node;
    }



Too many people use Contains and then [key] rather than TryGetValue, so thumbs up for getting that right. I would observe, though, that foo.TryGetValue(key, out val) ? val : defaultVal is a common enough pattern that you could consider factoring it out as an extension method to IDictionary&lt;K,V&gt; and IReadOnlyDictionary&lt;K,V&gt;.