2012-06-05 2 views
0

OR 연산에 아래의 방법을 사용할 때 중복 레코드가 반환됩니다. 사용자 지정 IEqualityComparer를 지정해야합니까?() 간단한 구별이어떻게해야합니까 다음과 같은 linq 일반 메서드는 고유 레코드를 반환합니까?

internal static IQueryable<T> FilterEntity<T>(filters filters, IQueryable<T> entities) 
    { 
     if (filters.groupOp == "AND") 
      foreach (var rule in filters.rules) 
       entities = entities.Where<T>(
        rule.field, rule.data, 
        (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op) 
        ); 
     else 
     { 
      //Or 
      IQueryable<T> temp = (new List<T>()).AsQueryable(); 
      foreach (var rule in filters.rules) 
      { 
       var t = entities.Where<T>(
        rule.field, rule.data, 
        (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op) 
        ); 

        temp = temp.Concat<T>(t).AsQueryable(); 
      } 
      entities = temp; 
     } 
     return entities; 
    } 

아래 @usr FROM SUGGESTION 편집 된 후 작동하지 않습니다 -이 나에게 (별개의)와 SQL 프로파일 러에서 올바른 쿼리를 제공하지만 너무 복잡한보고 시작 - 나는 청소기처럼 WD 용액

internal static IQueryable<T> FilterEntity<T>(filters filters, IQueryable<T> entities) 
    { 
     if (filters.groupOp == "AND") 
      foreach (var rule in filters.rules) 
       entities = entities.Where<T>(
        rule.field, rule.data, 
        (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op) 
        ); 
     else 
     { 
      //Or 
      var t1 = entities.Where<T>(filters.rules[0].field,filters.rules[0].data, 
       (WhereOperation)StringEnum.Parse(typeof(WhereOperation),filters.rules[0].op) 
       ); 
      for (int i = 1; i<filters.rules.Count(); i++) 
      { 

       var t = t1.Where<T>(filters.rules[i].field, filters.rules[i].data, 
       (WhereOperation)StringEnum.Parse(typeof(WhereOperation), filters.rules[i].op) 
       ); 
       t1.Concat<T>(t).AsQueryable(); 
      } 
      entities = t1; 
     } 
     return entities.Distinct<T>(); 
    } 
+0

거의 모든 LINQ 공급자에서 "새 목록 ()"을 LINQ 쿼리와 함께 사용할 수 없습니다. 이 코드는 원하는대로 작동하지 않습니다 (제대로 실행되지만). 데이터베이스를 너무 자주 호출하고 있습니다. 그것은 진짜 질문이 아닙니다. – usr

+0

내가 사용하는 각 규칙에 대해 하나의 쿼리를 생성합니다. 뚜렷한 일을하지 말라. 그것은 내가 원하는 것을하고 있습니다. 여러 동적 검색을 구현하는 더 좋은 방법이 있습니까? - 그것으로 전환하게되어 기쁩니다 –

+0

목록 대신 List 가있는 각 엔티티에 대해 별도의 필터 클래스를 작성하면 동일한 문제가 발생합니다. –

답변

1

Distinct()IEqualityComparer 또는 관련되지 않는다. 그것은 modified closure gotcha이다, 즉 : 루프 변수 rule는 루프 본문에 복사해야합니다 :

foreach (var rule in filters.rules) 
{ 
    var rule1 = rule; 
    // work with rule1 only. 

당신은이 작업을 수행하여을 Usr의 조언을 따를 수 있습니다 : 그것은 문제가 해결되는지

IQueryable<T> temp = null; 
    .... 
    foreach (var rule in filters.rules) 
    { 
     var rule1 = rule; 
     var t = entities.Where<T>(rule1.field, rule1.data, 
      (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule1.op)); 

      if (temp == null) 
       temp = t; 
      else 
       temp = temp.Union(t); // Union!! 
    } 
} 
return temp; 

궁금 . Union (암시적인 Distinct 임)의 사용에 유의하십시오. 문제가 해결되지 않으면 방해가되는 코드 (예 : WhereOperation)가 보이지 않는 것으로 보입니다.

+0

그다지 ... –

+0

괜찮습니까? 예외는 없습니까? –

+0

OR 연산에 지정된 둘 이상의 조건을 만족하는 레코드에 대해 중복 레코드가 반환됩니다 (클라이언트 쪽 눈금에 사용하고 있습니다) - 예외 없음 –

1

쿼리를 시작하려면 List<T>으로 시작하지 마십시오. 첫 번째 "t"부터 시작하십시오. 그렇게하면 서버에서 실행중인 쿼리 하나만 얻게됩니다. 별개의 결과를 얻으려면 Concat 대신 Union을 사용하십시오.

+0

노조가 작동하지 않습니다 - 목록없이 시작하는 방법을 보여 줄 수 있습니까

+0

첫 번째 솔루션으로 위에 구현되었습니다. 결과는 내가 필요로하는, SQL 프로파일 러를보고,하지만 이것은 해킹처럼 보이기 시작하고있다; 그것을 향상시킬 수 있습니까? –

+0

코드에서 일부 중복을 제거 할 수는 있지만 괜찮습니다. 너는 맞다. 다행이 당신을 위해 일하고 있습니다. – usr

관련 문제