从Func <t,t,=“”bool =“”> + T实例到表达式<func <t,bool =“”>&gt; </func <t,> </t,>

时间:2013-06-06 12:49:37

标签: c# linq-to-entities expression

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

中的两个Ts
var comparer = (a, b) => 
    a.IdPart1 == b.IdPart1 && a.IdPart2 == b.IdPart2;

我想用这个和T的具体实例创建一个Expression<Func<T, bool>>作为Where()的谓词,如

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。

可能吗? :)

2 个答案:

答案 0 :(得分:0)

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));

答案 1 :(得分:0)

假设您可以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);