C# Predicate Builder with "NOT IN" functionality
Asked Answered
W

4

7

With PredicateBuilder how do I get functionality similar to the SQL IN or NOT IN query?

For example I have a list of IDs and I want to select all of the People whose IDs either Match or do not match the IDs.

The people match functionality is fairly straightforward (although there may be a better way to do it)

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

So how do I get the opposite? I want all persons whose IDs are not in the personIDs list.

Willumsen answered 23/8, 2011 at 5:17 Comment(1)
As a workaround I was able to get the list of PersonIDs prefiltered so I can just use the code above. It's not ideal, but it will work.Willumsen
S
3

Ask De Morgan:

NOT (P OR Q) = (NOT P) AND (NOT Q)

To have your code generate the equivalent of a NOT IN condition, rewrite as

var predicate = PredicateBuilder.True<Person>()

and

predicate = predicate.And(e=>e.PersonID != temp);
Substructure answered 23/8, 2011 at 5:25 Comment(1)
That is what I tried the first time, however I am getting an empty result set from SQL. When I inspect the SQL from Profiler I get something to the effect of SELECT CAST(NULL as varchar(1)) as [C1], . . . FROM (SELECT 1 as X) AS [SingleRowTable1] WHERE 1=0Willumsen
V
3

Do you use Entity Framework?

Then you can build the query without PredicateBuilder:

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

From this LINQ statement a SQL NOT IN query is created.

Vicarage answered 23/7, 2012 at 8:48 Comment(0)
N
0

Is this what you want?

var predicate = PredicateBuilder.True<Person>()
foreach (int i in personIDs)
{
    int temp = i;
    predicate = predicate.And(e => e.PersonID != temp);
}
return persons.Where(predicate);
Nationalism answered 23/8, 2011 at 5:26 Comment(0)
P
0

Without looking at the 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);
Paprika answered 23/8, 2011 at 5:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.