2011-04-01 2 views
2

PredicateBuilder에 대한 질문이 있습니다.이 문제를 해결하는 방법에 대한 조언을 보내 주시면 감사하겠습니다. 나는 이것을 설명하려고 노력할 것이다.PredicateBuilder를 여러 번 사용하여 질문하거나 OR

사람들이 키워드를 기반으로 제품을 검색 할 수있는 경우가 있습니다. 각 키워드는 keywordgroup에 속하는, 그래서 일부 실제 데이터는 다음과 같습니다

KeywordGroup/키워드

유형 - 체인/

유형 - 팔찌/

색상 - 퍼플/

색 - 초록색

이제 다음 결과를 원합니다.

각기 다른 KeywordGroup 사이에는 OR이 있어야합니다. KeywordGroup 내의 각기 다른 키워드 사이에는 AND가 있어야합니다.

예를 들어, 사용자는 Purpleple 또는 Green 색상의 팔찌 만 검색하려고합니다.

이 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; 
     } 
    } 

================================는

그래도 작동하지 않습니다.

나를 도와 줄 수 있습니까?

감사합니다. Daniel

답변

0

이것은 단지 And 및문장의 큰 목록을 만드는 것입니다. 함께 그룹화해야합니다. 이 같은

뭔가 ..

 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.. 
     } 
3

는 각 키워드에 대한 루프에서 임시 변수를 사용해야합니다. 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)); 
} 

공지 사항 술어 AndOr를 사용하는 각 라인에서 temp의 사용.