编辑:i在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();...assuming StructureAnalyses是实体框架中的my StructureAnalysis对象的IQueryable。
但是假设我想获得任务,使用相关的StructureAnalyses进行过滤。如何做这样的事情?要记住,在现实中,query是由一个可重用的函数构建的,而predicate是在一个单独的函数中生成的,它调用它,所以我不能简单地合并这两个查询。
当我尝试执行查询时,它会编译但失败:
Tasks.AsExpandable().Where(predicate).Dump();...with“参数't‘在指定的LINQ实体查询表达式中没有绑定”,等等。在本例中,Tasks是一个IQueryable,它包含my中的所有Task类型实体。
我也试过改变这句话:
predicate = predicate.And(t => query.Invoke(t.StructureAnalysis));...to:
compiled = query.Compile();
predicate = predicate.And(t => compiled(t.StructureAnalysis));这也编译但失败了,“无法将'System.Linq.Expressions.FieldExpression‘类型的对象强制转换为’System.Linq.Expressions.LambdaExpression‘”。也可以理解。
我还尝试在query和compiled上调用query和compiled(这没有任何效果),以及以下“解决方案”:
发布于 2015-01-27 14:08:22
最后我自己找到了解决办法。诀窍是将query调用封装在访问该属性的另一个谓词中,然后在调用该谓词时展开该谓词。因此,对于我试图在单个StructureAnalysis上调用查询的示例,我的代码现在如下所示:
// 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
);
//// HERE'S WHAT'S NEW ////
Expression<Func<Task, bool>> subPredicate = t => query.Invoke(t.StructureAnalysis);
predicate = predicate.And(subPredicate.Expand());
Tasks.AsExpandable().Where(predicate).Dump();https://stackoverflow.com/questions/28156503
复制相似问题