将两个不同的谓词生成器与表达式相结合

本文关键字:谓词 相结合 表达式 两个 | 更新日期: 2023-09-27 18:24:42

我有一个谓词生成器,它运行良好

 var filter = sortKeys.Aggregate(filter, (currentFilter, sortkey) => currentFilter.Or(
                            x => x.Appointments.Any(y => y.RowStatus == Constants.CurrentRowStatus )));

我现在正试图将约会中的条件拆分为另一个谓词生成器,这样我就可以在旅途中添加条件并重用该函数。

我曾尝试创建一个表达式,然后在主谓词生成器中使用它,但失败了

private static Expression<Func<Appointment, bool>> TmpApt(string status)
    {
        var predicate = PredicateBuilder.False<Appointment>();
        predicate = predicate.Or(p => p.RowStatus == status);
        return predicate;
    }

将主谓词更改为使用上面的表达式

var filter = sortKeys.Aggregate(PredicateBuilder.True<Person>(), (current, s) =>
                                current.Or(x => x.Appointments.Any(TmpApt(s))));

它显示了一个错误

参数类型"System.Linq.Expressions.Expression<System.Func<Appointment,bool>>"为不可分配给参数类型System.Func<Appointment,bool>

我甚至尝试过像Expand这样的LinqKit扩展方法,但可以找到解决方案。

在LINQ中也尝试了可重用谓词表达式,然后它在编译时没有显示任何错误,但在应用程序端,它显示

不支持用于查询运算符"Any"的重载。

有人能帮我解决这个错误吗?或者建议一个替代的解决方案。

将两个不同的谓词生成器与表达式相结合

您可以使用LINQKit来调用您想要使用它的位置处的表达式:

var predicate = TmpApt();
var filter = sortKeys.Aggregate(PredicateBuilder.False<Person>(),
    (current, s) => current.Or(x =>
        x.Appointments.Any(appointment => predicate.Invoke(appointment))))
        .Expand();

请注意,您需要将TmpApt拉出到一个变量中,以便LINQKit成功评估它,因为它的实现中存在一个错误。

还要注意,您需要将聚合操作初始化为False,因为True与任何东西的OR运算都是true

还要注意,您可以将TmpApt的实现简化为以下内容:

private static Expression<Func<Appointment, bool>> TmpApt()
{
    return p => p.RowStatus == Constants.CurrentRowStatus;
}

这里不需要使用谓词生成器来Or,而是使用False