2013-06-11 3 views
2

검색 할 필드 조합 목록이 있습니다. 목록에는 실제로 최대 100 개의 항목이 포함될 수 있으며 쿼리하는 테이블에는 현재 1 백만 개가 넘는 레코드가 있습니다.필드 조합 목록이있는 Where 절

예 : 데이터를 검색 할

create table mytable 
(
    foo int not null 
    ,bar int not null 
    ,baz int not null 
) 

insert into 
    mytable 
values 
    (1, 1, 11) 
    ,(1, 2, 12) 
    ,(1, 3, 13) 
    ,(2, 1, 21) 
    ,(2, 2, 22) 
    ,(2, 3, 23) 
    ,(3, 1, 31) 
    ,(3, 2, 32) 
    ,(3, 3, 33) 

한 가지 가능한 방법 :

select 
    foo 
    ,bar 
    ,baz 
from 
    mytable 
where 
    (foo = 1 and bar = 3) 
    or (foo = 2 and bar = 1) 
    or (foo = 3 and bar = 2) 

또 다른 가능한 방법 :

foo   bar   baz 
----------- ----------- ----------- 
1   3   13 
2   1   21 
3   2   32 
:

declare @filtercombos table 
(
    foo int not null 
    ,bar int not null 
) 

insert into 
    @filtercombos 
values 
    (1, 3) 
    ,(2, 1) 
    ,(3, 2) 

select 
    mytable.foo 
    ,mytable.bar 
    ,mytable.baz 
from 
    @filtercombos fc 
    left join mytable on mytable.foo = fc.foo and mytable.bar = fc.bar 

모두이 데이터를 반환합니다

이제 이것이 단일 값 목록 인 경우 .Where(item => myList.Contains(item.foo))을 할 수 있습니다. 위와 같은 쿼리를 어떻게 수행 할 수 있습니까? 내가 생각할 수있는 유일한 것은 DbContext에서 SQL을 실행하는 것이지만 가능한 경우이를 피하고 싶습니다.

답변

3

LINQKit의 PredicateBuilder는 당신이 필요합니다!

var query = from u in context.Users select u; 
var pred = Predicate.False<User>(); 

foreach(var filter in combofilers) 
    pred = pred.Or(u => u.Username == filter.Foo && u.Language == filter.Bar); 

return query.Where(pred.Expand()).FirstOrDefault(); 
// or return query.AsExpandable().Where(pred).FirstOrDefault(); 

Dynamic where clause (OR) in Linq to Entities

+0

이 경우 프로필러는 검색어가 ' (foo = 1 및 bar = 3) 또는 (foo = 2 및 bar = 1) 또는 (foo = 3 및 bar = 2)'로 확장되었음을 보여줍니다. – Stijn

0

다른 목록에 이미 조합 목록이있는 경우 다음과 같이 할 수 있습니다.

var query = from m in Context.mytables 
    select m; 

foreach (var foobar in foobars) 
{ 
    query = query.Where(x => x.foo == foobar.foo && x.bar == foobar.bar); 
} 

return query.ToList(); 
+0

는''체이닝 Where' and' 동작이다. – Stijn

+0

죄송합니다. 나는 자세히 보지 않았습니다. 또는이 질문의 Predicate Builder 솔루션을 사용할 수 있습니다. http://stackoverflow.com/questions/782339/how-to-dynamically-add-or-operator-to-where-clause-in-linq –

+0

여기에 더 좋은 예가 있습니다. http://stackoverflow.com/questions/2101540/linq-or-equivalent-of-where –

0

또는이 질문에 대한 답과 비슷한 것이 도움이 될 수 있습니다.

Entity Framework - Join to a List

+0

그 첫 번째 솔루션은 저장 프로 시저 (DbContext에서 SQL을 실행하는 것과 유사 함)입니다. 설명 된 두 번째 솔루션은 메모리에있는 모든 레코드를 가져옵니다.이 레코드는 백만 개가 넘는 레코드로는 처리 할 수 ​​없습니다. – Stijn