我有一个关于PredicateBuilder的问题,我真的希望你能给我一些建议来解决这个问题。我会试着解释这一点。
我有一个案例,人们可以根据关键字搜索产品。每个关键字都属于一个关键字组,因此一些实际数据将是:
KeywordGroup /关键字
Type - Chain/
类型-手环/
颜色-紫色/
颜色-绿色
现在,我希望得到以下结果:
在每个不同的KeywordGroup之间应该有一个OR。在KeywordGroup中的每个不同关键字之间应该有一个AND。
因此,例如,用户想要仅搜索具有紫色或绿色的手镯。
使用此PredicateBuilder可以实现此目的吗?
这就是我到目前为止所知道的:
================================
/// <summary>
/// Search for products
/// </summary>
/// <param name="itemsPerPage"></param>
/// <returns></returns>
public List<Product> SearchProducts(int from, int max, string sorting, List<Keyword> filter, out int totalitems) {
try {
var predicate = PredicateBuilder.True<Product>();
KeywordGroup previousKeywordGroup = null;
foreach (Keyword k in filter.OrderBy(g=>g.KeywordGroup.SortOrder)) {
if (previousKeywordGroup != k.KeywordGroup) {
previousKeywordGroup = k.KeywordGroup;
predicate = predicate.And(p => p.Keywords.Contains(k));
}
else
predicate = predicate.Or(p => p.Keywords.Contains(k));
}
var products = context.Products.AsExpandable().Where(predicate);
//var products = from p in context.Products
// from k in p.Keywords
// where filter.Contains(k)
// select p;
totalitems = products.Distinct().Count();
if (sorting == "asc")
return products.Where(x => x.Visible == true).Distinct().Skip(from).Take(max).OrderBy(o => o.SellingPrice).ToList();
else
return products.Where(x => x.Visible == true).Distinct().Skip(from).Take(max).OrderByDescending(o => o.SellingPrice).ToList();
}
catch (Exception ex) {
throw ex;
}
}================================
不过,它不起作用。
你能帮帮我吗?
谢谢!丹尼尔
发布于 2011-04-01 22:40:03
您需要在循环中为每个关键字使用一个临时变量。从Predicate Builder page
循环中的临时变量是为了避免外部变量陷阱而需要的,在外部变量陷阱中,对于foreach循环的每次迭代都会捕获相同的变量。
试着这样做:
foreach (Keyword k in filter.OrderBy(g=>g.KeywordGroup.SortOrder)) {
Keyword temp = k;
if (previousKeywordGroup != k.KeywordGroup) {
previousKeywordGroup = k.KeywordGroup;
predicate = predicate.And(p => p.Keywords.Contains(temp));
}
else
predicate = predicate.Or(p => p.Keywords.Contains(temp));
}请注意,在使用谓词And和Or的每一行中都使用了temp。
发布于 2011-04-01 21:16:26
这只是一个很大的And和Or语句列表,您需要将它们组合在一起。
像这样的东西..
var grouped = filter.GroupBy(item => item.KeyWordGroup, item => item.KeyWords);
foreach (var item in grouped)
{
var innerPredicate = PredicateBuilder.True<Product>();
foreach (var inner in item)
{
innerPredicate = innerPredicate.Or(p => item.Contains(k));
}
predicate = predicate.And(innerPredicate); //not sure this is correct as dont have IDE..
}https://stackoverflow.com/questions/5513617
复制相似问题