如何将 N 个表达式树与 OR/And 运算符组合

How to combine N amount of expression trees with OR/And operators

目前我有一个表达式树,以 Expression<Func<Project, bool>> 的形式表示 MONSTOROUS Lambda 我这样做是为了用Linq.

这里是冰山一角。

        return prj => !FilterCriteria.IsFilterEnabled && prj.OrganizationID != null
                      || (((FilterCriteria.OrganiazaitonId == null) || organizationIDs.Contains(prj.OrganizationID.Value))
                       || ((FilterCriteria.ActivityTypeId == null) || (act.ActivityTypeID == FilterCriteria.ActivityTypeId))
                          && ((FilterCriteria.ProductLineId == null) || (prj.ProductLineID == FilterCriteria.ProductLineId))
                          && ((FilterCriteria.ProjectTypeId == null) || (prj.ProjectTypeID == FilterCriteria.ProjectTypeId))
                          && ((FilterCriteria.ProjectId == null) || (prj.ProjectID == FilterCriteria.ProjectId))
                          && ((FilterCriteria.StartDateFrom == null) || (prj.StartDate >= FilterCriteria.StartDateFrom))
//... this goes on for about 40 more lines

我已经将这些 expression trees 分为 6 类,并希望根据条件语句将它们组合起来。 基本示例

if(...){
        Expression<Func<Project, bool>> filterEnabled = prj => !FilterCriteria.IsFilterEnabled && prj.OrganizationID != null;
 }
 else if(...){       //combined with `OR` statement

        Expression<Func<Project, bool>> organizations = prj => organizationIDs.Contains(prj.OrganizationID.Value);
 }   
 else if (...){       //combined with `AND` statement

        var projectType = prj => (prj.ProjectTypeID == FilterCriteria.ProjectTypeId);
 }
...

如何将它们组合成一个 expression tree?

这应该很简单,只需使用 Expression.AndExpression.Or 调用在单个表达式树调用中聚合各种表达式。让我举个例子,如果你有一个 List<Expression>,它需要聚合成单一表达式然后使用下面的代码使用 And 聚合,例如,它可以是任何谓词构建器:

    List<Expression> exptree = new List<Expression>();

    var resultEXpression = exptree.Skip(1).Aggregate(exptree.FirstOrDefault(), 
    (exp1,exp2) => Expression.And(exp1,exp2));

这只是一个示例,默认有很多表达式构建器,可以帮助根据相关逻辑将表达式绑定在一起,可以是Or, AndAlso, OrAssign, OrElse