从 Func + T 实例到 Expression>.

本文关键字:bool Func Expression 实例 | 更新日期: 2023-09-27 18:17:08

如果我有Func<T, T, bool>告诉我如何比较两个 Ts,如

var comparer = (a, b) => 
    a.IdPart1 == b.IdPart1 && a.IdPart2 == b.IdPart2;

我想使用它和 T 的具体实例来创建用作 Where(( 谓词的Expression<Func<T, bool>>,例如

T instance = GetSomeT();
TRepository.GetAll().Where(x => 
    x.IdPart1 == instance.IdPart1 && x.IdPart2 == instance.IdPart2);

但当然是动态的,这样我就可以写

var predicate = something depending on comparer and instance;
TRepository.GetAll().Where(predicate);

可能吗?

更酷的是,如果我可以从 T 动态创建谓词,并且在所有属性之间使用 KeyAttribute 和 and 相等,并且介于两者之间,这样我就不需要比较器,只需要 T。

这可能吗?:)

从 Func<T, T, bool> + T 实例到 Expression<Func<T, bool>>.

假设你可以comparer作为Expression<Func<T, T, bool>>,那么你可以使用LINQKit来做到这一点。

像这样:

Expression<Func<Foo, Foo, bool>> comparer =
    (a, b) => a.IdPart1 == b.IdPart1 && a.IdPart2 == b.IdPart2;
Foo instance = …;
Expression<Func<Foo, bool>> predicate = x => comparer.Invoke(x, instance);
var expandedPredicate = predicate.Expand();
var result = FooRepository.GetAll().Where(expandedPredicate);

Expand()部分很重要,因为这就是 LINQKit 的"魔力"发生的地方。执行相同操作的语法略有不同,即改用AsExpandable()

var result = FooRepository.GetAll().AsExpandable().Where(predicate);
T instance = GetSomeT();
Predicate<T> MyPredicate = x => comparer(x, instance);
TRepository.GetAll().Where(MyPredicate);

考虑到下面给出的评论,这是您如何制定Expression<Func<T, bool>>

T instance = GetSomeT();
Expression<Func<T, bool>> Exp = x => comparer(x, instance);
TRepository.GetAll().Where(Exp);

这是完全相同的,只是不同的var类型。

简而言之,您可以:

TRepository.GetAll().Where(x => comparer(x, instance));