2009-04-02 3 views
3

이것은 나를 위해 일한 후 실패했습니다. 모든 필터가 포함 된 항목 만 반환하고 하나 이상의 필터는 현재하고 싶지 않습니다. 여기서 뭐가 틀렸어? - 기본적으로 AND다른 모음의 내용에서 항목 모음 필터링

foreach(string s in filters) { 
    if(s.Length == 0) continue; 
    string tmp = s; // because of "capture" problem 
    index = index.Where(i => i.FilterNames.Contains(tmp)); 
} 
return index; 

이 모든 필터를 덮고, Where 조항의 연속을 적용 같은 것에 대해 어떻게

private IQueryable<IndexItem> FilteredIndex (IQueryable<IndexItem> index, IEnumerable<string> filters) 

    { 

     var filteredIndex= from f in filters.AsQueryable() 
       where f.Length>0 
       from i in index 
       where i.FilterNames.Contains(f) 
       select i; 
     return filteredIndex; 
    } 
+0

어떤 LINQ 공급자를 사용하고 있습니까? IQueryable을 사용하여 LINQ to Objects가 아닌 것으로 가정합니다. –

+0

LINQ for Objects에 대해 꽤 우아한 솔루션을 제공 할 수 있지만 실제로 작동하는지 여부는 확실하지 않습니다. 만약 그렇다면 나에게 들려줘. –

답변

1

.

+0

"캡처"란 무엇입니까? – zsharp

+0

@zsharp Where() 내부의 람다가 클로저입니다. 해당 반복에 대한 변수 s는 그렇지 않으면 lambda가 실행 된 시간에 따라 달라집니다. 클로저를 참조하십시오. – CVertex

+0

람다에서 "s"를 사용하기 때문에 실제로 컴파일러에서 생성 된 클래스의 필드로 처리됩니다 (복잡한 이유로). 문제는 "foreach"의 성격은 그렇지 않다면 그 중 하나만 가져오고 n 시간은 Where ([last filter])가된다는 것을 의미합니다. –

1

주위를 뒤집습니다. 원하는 것은 FilterNames의 모든 항목에 필터에 해당 항목이있는 색인의 항목입니다. 나는 그것이 얼마나 효과적 일지 모르겠지만 카운트 비교는해야만합니다. 예 :

private IQueryable<IndexItem> FilteredIndex(IQueryable<IndexItem> index, IEnumerable<string> filter) 
{ 
    var filteredIndex = from i in index 
         where (from s in i.FilterNames 
           where filter.Contains(s) 
           select s).Count() == i.FilterNames.Count 
         select i; 
    return filteredIndex; 
} 
3

스트레이트 포워드 인덱스 체크로부터 주어진 아이템에 대해, 주어진 아이템이 필터를 포함하고있는 모든 필터들에 대해 참이라는 것을 확인하십시오. 이것으로 주어진 조건을 만족하는 모든 항목을 색인에서 선택합니다.

index.Where(item => 
    filters.All(filter => item.FilterNames.Contains(filter))) 

길이가 0보다 큰지 확인해야하는지 잘 모르겠 으면 쉽게 통합 할 수 있습니다.

index.Where(item => 
    filters.All(filter => 
     (filter.Length > 0) || (item.FilterNames.Contains(filter)))) 

그것은 객체에 LINQ와 함께 작동 난 당신이 원하는 것을 생각하지만 SQL에 LINQ와 함께 작동 있는지 확실하지 않다.

관련 문제