编辑:我设法减少我的代码在LinqPad的协助下最小公分母。使用LinqKit将查询应用到一个复杂属性
我有一个方法返回一个复杂的LinqKit谓词。期望的结果是能够在我需要执行此查询时重用此方法。它可以在Where
子句中针对这些实体的集合工作正常,但是我不能在我将这个实体作为对象的单个属性并且想要使用谓词的时候弄清楚如何使用这个谓词查询该实体的其他属性。
我会给你一个简单的例子,我的意思是。
// 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
是我从实体框架StructureAnalysis
对象的IQueryable
。
但是,让我们说我想获取任务,使用相关的StructureAnalyses进行筛选。 我该怎么做这样的事情?请记住,实际上,query
是由可重复使用的函数构建而成的,而predicate
是在调用它的单独函数中构建的,所以我不能简单地合并这两个查询。
它编译,但是当我尝试和执行查询失败:
Tasks.AsExpandable().Where(predicate).Dump();
与...“参数‘T’在指定的LINQ到实体没有义务查询表达式。”等。在这个例子中,Tasks
是一个IQueryable,它包含我DB中的所有Task
类型实体。
我也试着改变这一行:
predicate = predicate.And(t => query.Invoke(t.StructureAnalysis));
...到:
compiled = query.Compile();
predicate = predicate.And(t => compiled(t.StructureAnalysis));
这也编译,但失败,“无法投类型的对象“系统。 Linq.Expressions.FieldExpression'键入'System.Linq.Expressions.LambdaExpression'。“,可以理解。
我也试过在两个query
和compiled
,这都没有效果,以及下面的“解决方案”,呼吁Expand
:
- 这一次似乎不完整的(
Utility
是不确定的): https://stackoverflow.com/questions/26105570/linqkit-the-parameter-was-not-bound-in-the-specified-linq-to-entities-query-e - 这一个简单地说,“这不能做”,我不相信: Entity Framework Code First 4.3/LINQKit predicate for related table
我认为提出的关闭原因是无效的。 – Shoe 2015-01-26 19:29:56
@Shoe代码提供的不会重现问题;紧密的原因完全有效。或者你是否能够使用提供的代码重现所描述的问题? – Servy 2015-01-26 21:37:23
@Servy前段时间更新了问题,并在评论中回复了您的答案。我很确定你现在可以重现它,但是如果你不能,请告诉我。 – Grinn 2015-01-26 21:44:27