Mik*_*uck 5 c# linq linq-to-sql predicatebuilder
假设我通过 LINQ 查询创建了一些匿名类型:
var query = from Person in db.People
join Pet in Pets on Person.ID equals Pet.PersonID
join Thingy in Thingies on Person.ID equals Thingy.PersonID
select new {
Person.ID,
PetName = Pet.Name,
Thing = Thingy.Thing,
OtherThing = Thingy.OtherThing
};
Run Code Online (Sandbox Code Playgroud)
现在我想通过动态构建谓词将一些复杂的表达式应用于查询。我对已知类型所做的事情是这样的:
var predicate = PredicateBuilder.False<MyType>();
predicate = predicate.Or(myType => myType.Flag);
if (someCondition) {
var subPredicate = PredicateBuilder.True<MyType>();
subPredicate = subPredicate.And(myType => myType.Thing == someThing);
subPredicate = subPredicate.And(myType => myType.OtherThing == someOtherThing);
predicate = predicate.Or(subPredicate);
}
query = query.Where(predicate);
Run Code Online (Sandbox Code Playgroud)
是否可以对匿名类型做类似的事情?我还没有找到一种使用匿名类型的方法,PredicateBuilder我也不熟悉任何其他可以让我动态构建这样的表达式的构造。如果没有,在为查询动态生成嵌套表达式时,我应该采用另一种方法吗?
假设所有你需要的是PredicateBuilder.False<T>和PredicateBuilder.True<T>一个匿名类型,你可以做这样的:
private static Expression<Func<T,bool>> MakeTrue<T>(IQueryable<T> ignored) {
return PredicateBuilder.True<T>();
}
private static Expression<Func<T,bool>> MakeFalse<T>(IQueryable<T> ignored) {
return PredicateBuilder.False<T>();
}
Run Code Online (Sandbox Code Playgroud)
现在,您无需显式使用匿名类型即可重写代码:
var predicate = MakeFalse(query);
predicate = predicate.Or(v => v.ID > 10000);
query = query.Where(predicate);
Run Code Online (Sandbox Code Playgroud)
这个想法是让编译器为你做类型推断。不幸的是,您最终会得到一个未使用的方法参数。