编辑:在 LinqPad 的帮助下,我设法将我的代码减少到最小公分母。
我有一个返回复杂 LinqKit 谓词的方法。期望的结果是能够在我需要执行此查询时重用此方法。它在Where
针对这些实体的集合的子句中运行良好IQueryable
,但是当我将此实体作为对象的单个属性并想使用谓词进行查询时,我无法终生弄清楚如何使用此谓词该实体的其他属性。
我会给你一个简单的例子来说明我的意思。
// Note: .Includes removed for brevity's sake.
var task = Tasks.First(t => t.QaConfigTaskId == 2);
var predicate = PredicateBuilder.True<Task>();
// Ensure that the task's own properties match.
predicate = predicate.And(t => t.TaskType == task.TaskType &&
t.Description == task.Description &&
t.PreTreatment == task.PreTreatment &&
t.Treatment == task.Treatment);
var structureAnalysis = task.StructureAnalysis;
var query = PredicateBuilder.True<StructureAnalysis>();
query = query.And(analysis =>
// The names match
analysis.Name == structureAnalysis.Name &&
// We have the same # of goals so they must all match.
analysis.Goals.Count == structureAnalysis.Goals.Count
);
predicate = predicate.And(t => query.Invoke(t.StructureAnalysis));
这将正常工作:
StructureAnalyses.AsExpandable().Where(query).Dump();
...假设StructureAnalyses
是IQueryable
我的一个StructureAnalysis
来自 Entity Framework 的对象。
但是假设我想获取任务,使用相关的结构分析进行过滤。我怎么能做这样的事情?请记住,实际上,query
它是由可重用函数predicate
构建的,并且是在调用它的单独函数中构建的,因此我不能简单地合并两个查询。
它编译但当我尝试执行查询时失败:
Tasks.AsExpandable().Where(predicate).Dump();
...带有“参数 't' 未绑定在指定的 LINQ to Entities 查询表达式中。” ,或类似的。在此示例中,Tasks
是一个 IQueryable,它包含Task
我的数据库中的所有类型实体。
我也试过改变这一行:
predicate = predicate.And(t => query.Invoke(t.StructureAnalysis));
...至:
compiled = query.Compile();
predicate = predicate.And(t => compiled(t.StructureAnalysis));
这也可以编译但失败,“无法将'System.Linq.Expressions.FieldExpression'类型的对象转换为'System.Linq.Expressions.LambdaExpression'。” 这是可以理解的。
我也尝试过调用Expand
and query
,compiled
但没有效果,以及以下“解决方案”: