2011-08-23 18 views
6

Z PredicateBuilder jaki sposób uzyskać funkcjonalność podobną do SQL czy nie w kwerendzie?C# Builder bazowe z "NOT IN" funkcjonalności

Na przykład mam listę identyfikatorów i chcę, aby wybrać wszystkie osoby, których identyfikatory bądź pasują, nie pasują do identyfikatorów.

Funkcjonalność ludzie mecz jest dość prosta (choć może być lepszy sposób to zrobić)

var predicate = PredicateBuilder.False<Person>() 
foreach (int i in personIDs) 
{ 
    int temp = i; 
    predicate = predicate.Or(e=>e.PersonID == temp); 
} 
return persons.Where(predicate); 

Więc jak mogę coś przeciwnego? Chcę wszystkich osób, których identyfikatory nie znajdują się na liście ID person.

+0

Jako obejście I był w stanie uzyskać listę PersonIDs filtracji wstępnej, więc mogę po prostu użyć powyższy kod. To nie jest idealne, ale zadziała. –

Odpowiedz

3

Zapytaj De Morgan:

NIE

(P lub Q) = (NIE P) i (NIE Q)

Aby mieć swój kod generuje odpowiednik NOT IN stanie przepisać jako

var predicate = PredicateBuilder.True<Person>() 

i

predicate = predicate.And(e=>e.PersonID != temp); 
+0

To jest to, co próbowałem za pierwszym razem, jednak otrzymuję pusty zestaw wyników z SQL. Kiedy sprawdzać SQL z Profiler mam coś do skutku SELECT CAST (NULL jako varchar (1)) jako [C1], . . . OD (SELECT 1 jako X), [SingleRowTable1] gdzie 1 = 0 –

0

Czy tego chcesz?

var predicate = PredicateBuilder.True<Person>() 
foreach (int i in personIDs) 
{ 
    int temp = i; 
    predicate = predicate.And(e => e.PersonID != temp); 
} 
return persons.Where(predicate); 
0

bez patrzenia na api ....

var predicate = PredicateBuilder.True<Person>() 
foreach (int i in personIDs) 
{ 
    int temp = i; 
    predicate = predicate.And(e=>e.PersonID != temp); 
} 
return persons.Where(predicate); 
3

Używasz Entity Framework?

Następnie można zbudować kwerendę bez PredicateBuilder:

var personIds = new List<int>() { 8,9,10 }; 
var query = persons.Where(it => !personIds.Contains(it.PersonId)); 

Z tym stwierdzeniem LINQ to SQL nie jest tworzona w kwerenda.