C# PredicateBuilder多重与或的问题

C# PredicateBuilder多重与或的问题,c#,predicatebuilder,C#,Predicatebuilder,我有一个关于PredicateBuilder的问题,我真的希望你能给我一些关于如何解决这个问题的建议。我会尽力解释的 我有一个案例,人们可以根据关键词搜索产品。每个关键字都属于一个关键字组,因此一些实际数据可能是: 关键字组/关键字 类型链/ 类型-手镯/ 颜色-紫色/ 颜色-绿色 现在我想得到以下结果: 在每个不同的关键字组之间应该有一个OR。 在关键字组中的每个不同关键字之间应该有一个AND 例如,一个用户只想搜索带有紫色或绿色的手镯 这个PredicateBuilder是否可以实现这一点

我有一个关于PredicateBuilder的问题,我真的希望你能给我一些关于如何解决这个问题的建议。我会尽力解释的

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

关键字组/关键字

类型链/

类型-手镯/

颜色-紫色/

颜色-绿色

现在我想得到以下结果:

在每个不同的关键字组之间应该有一个OR。 在关键字组中的每个不同关键字之间应该有一个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;
        }
    }
//
///搜索产品
/// 
/// 
/// 
公共列表搜索产品(int-from、int-max、字符串排序、列表过滤器、out-int-totalitems){
试一试{
var predicate=PredicateBuilder.True();
关键字组previousKeywordGroup=null;
foreach(filter.OrderBy(g=>g.KeywordGroup.SortOrder)中的关键字k){
if(previousKeywordGroup!=k.KeywordGroup){
previousKeywordGroup=k.KeywordGroup;
谓词=谓词和(p=>p.Keywords.Contains(k));
}
其他的
谓词=谓词。或(p=>p.Keywords.Contains(k));
}
var products=context.products.AsExpandable().Where(谓词);
//var products=来自context.products中的p
//从k到p.关键字
//其中filter.Contains(k)
//选择p;
totalitems=products.Distinct().Count();
如果(排序==“asc”)
return products.Where(x=>x.Visible==true).Distinct().Skip(from).Take(max).OrderBy(o=>o.SellingPrice).ToList();
其他的
return products.Where(x=>x.Visible==true).Distinct().Skip(from).Take(max).OrderByDescending(o=>o.SellingPrice.ToList();
}
捕获(例外情况除外){
掷骰子;
}
}
================================

/// <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;
        }
    }
不过,它不起作用

你能帮我吗

谢谢!
Daniel

这只是一个大列表,列出了
语句,您需要将它们组合在一起

像这样的

        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..
        }
var group=filter.GroupBy(item=>item.KeyWordGroup,item=>item.KeyWords);
foreach(分组中的var项目)
{
var innerPredicate=PredicateBuilder.True();
foreach(项目中的内部变量)
{
innerPredicate=innerPredicate.Or(p=>item.Contains(k));
}
predicate=predicate.And(innerPredicate);//不确定这是否正确,因为没有IDE。。
}

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

循环中的临时变量是 需要避免外部变量 陷阱,其中相同的变量是 为的每个迭代捕获 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));
}
注意在使用谓词
的每一行中使用
temp