首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PredicateBuilder多个AND OR问题

PredicateBuilder多个AND OR问题
EN

Stack Overflow用户
提问于 2011-04-01 20:50:46
回答 2查看 3.6K关注 0票数 2

我有一个关于PredicateBuilder的问题,我真的希望你能给我一些建议来解决这个问题。我会试着解释这一点。

我有一个案例,人们可以根据关键字搜索产品。每个关键字都属于一个关键字组,因此一些实际数据将是:

KeywordGroup /关键字

Type - Chain/

类型-手环/

颜色-紫色/

颜色-绿色

现在,我希望得到以下结果:

在每个不同的KeywordGroup之间应该有一个OR。在KeywordGroup中的每个不同关键字之间应该有一个AND。

因此,例如,用户想要仅搜索具有紫色或绿色的手镯。

使用此PredicateBuilder可以实现此目的吗?

这就是我到目前为止所知道的:

================================

代码语言:javascript
复制
/// <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;
        }
    }

================================

不过,它不起作用。

你能帮帮我吗?

谢谢!丹尼尔

EN

回答 2

Stack Overflow用户

发布于 2011-04-01 22:40:03

您需要在循环中为每个关键字使用一个临时变量。从Predicate Builder page

循环中的临时变量是为了避免外部变量陷阱而需要的,在外部变量陷阱中,对于foreach循环的每次迭代都会捕获相同的变量。

试着这样做:

代码语言:javascript
复制
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));
}

请注意,在使用谓词AndOr的每一行中都使用了temp

票数 3
EN

Stack Overflow用户

发布于 2011-04-01 21:16:26

这只是一个很大的AndOr语句列表,您需要将它们组合在一起。

像这样的东西..

代码语言:javascript
复制
        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..
        }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5513617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档