2

PredicateBuilder について質問があります。これを解決する方法についてアドバイスをいただければ幸いです。これを説明しようと思います。

キーワードで商品を探すケースがあります。各キーワードはキーワード グループに属しているため、実際のデータは次のようになります。

KeywordGroup / キーワード

タイプ - チェーン/

タイプ - ブレスレット/

カラー - パープル/

カラー - グリーン

今、私は次の結果を得たいと思っています:

それぞれの異なる 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;
        }
    }

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

しかし、うまくいきません。

あなたは私を助けることができます?

ありがとう!ダニエル

4

2 に答える 2

3

各キーワードのループで一時変数を使用する必要があります。Predicate Builder ページから:

ループ内の一時変数は、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が使用されtempている各行での使用に注意してください。AndOr

于 2011-04-01T14:40:03.317 に答える
1

Andこれはandsステートメントの大きなリストを作成しているだけ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..
        }
于 2011-04-01T13:16:25.853 に答える