【发布时间】:2016-12-09 17:42:24
【问题描述】:
我正在尝试构建一个表达式,最终导致类似的查询
SELECT p.*
FROM MyEntity p
WHERE EXISTS(SELECT *
FROM filters
WHERE (filter.type = 1
AND filter.objectid = p.id
AND filter.value = 1
OR filter.type = 1
AND filter.objectid = p.id
AND filter.value = 2))
AND EXISTS(...)
显然它看起来并不完全一样,但这是大体的想法。 我使用PredicateBuilder 根据传入的过滤器构建查询,所以我有这样的东西:
var query = context.Set<MyEntity>().AsExpandable();
var predicate = PredicateBuilder.New<MyEntity>(true);
//loop through the group filters. The filters in a group have an or relationship
foreach (FilterGroup group in filters)
{
predicate = predicate.And(
p => context.Set<FilteringValue>().AsExpandable().Any(getFilteringPredicate(p,group ))
);
}
return query.Where(predicate);
还有getFilteringPredicateMethod:
Expression<Func<FilteringValue,bool>> getFilteringPredicate(MyEntity p, FilterGroup filters) {
var fPredicate = PredicateBuilder.New<FilteringValue>(true);
foreach(var filter in filters.FilterList)
{
fPredicate= fPredicate.Or(fv => fv.objectid == p.Id && fv.Type== 1 && fv.value == filter.Value);
}
return fPredicate
}
这看起来比较简单,但是我得到了错误
从范围“”引用的“Models.MyEntity”类型的变量“p”,但未定义。
有没有办法将产品对象传递给 getFilteringPredicate() 方法? MyEntity 和 Filter 在 Entity Framework 中不相关。
【问题讨论】:
-
不是一个完整的答案,但您应该在使用
Ors 时将getFilteringPredicate中的谓词构建器fPredicate初始化为 false。var fPredicate = PredicateBuilder.New<FilteringValue>(true);应该是var fPredicate = PredicateBuilder.New<FilteringValue>(false); -
还有
MyEntity and Filter are not related in Entity Framework.——他们可能应该是相关的。 -
我将对此进行更详细的分析,我最初的测试看起来很好,我以为我有答案,但事实并非如此。我会给它第二次拍摄并发布答案
-
您能否发布“至少部分”您的
MyEntity、FilterGroup和FilterValue的样子?它们都是在 EF 模型中映射的实体吗? -
拜托,看看我的回答,我想出了一个更好的方法来使用连接(是的,Linq 和 EF 支持它们),但现在真的没有时间。如果我的回答对你有用,请告诉我,我会发布替代方法(我喜欢 Linq、Expressions 和 LinqKit 顺便说一句:))
标签: c# entity-framework linq linq-to-sql predicatebuilder