How would you do a “not in” query with LINQ?

2019-01-01 09:44发布

I have two collections which have property Email in both collections. I need to get a list of the items in the first list where Email does not exist in the second list. With SQL I would just use "not in", but I do not know the equivalent in LINQ. How is that done?

So far I have a join, like...

var matches = from item1 in list1
join item2 in list2 on item1.Email equals item2.Email
select new { Email = list1.Email };

But I cannot join since I need the difference and the join would fail. I need some way of using Contains or Exists I believe. I just have not found an example to do that yet.

标签: c# linq
15条回答
与君花间醉酒
2楼-- · 2019-01-01 10:17

Example using List of int for simplicity.

List<int> list1 = new List<int>();
// fill data
List<int> list2 = new List<int>();
// fill data

var results = from i in list1
              where !list2.Contains(i)
              select i;

foreach (var result in results)
    Console.WriteLine(result.ToString());
查看更多
零度萤火
3楼-- · 2019-01-01 10:18
var secondEmails = (from item in list2
                    select new { Email = item.Email }
                   ).ToList();

var matches = from item in list1
              where !secondEmails.Contains(item.Email)
              select new {Email = item.Email};
查看更多
柔情千种
4楼-- · 2019-01-01 10:21

I did not test this with LINQ to Entities:

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where !dc.Orders.Any(o => o.CustomerID == c.CustomerID)   
    select c;

Alternatively:

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where dc.Orders.All(o => o.CustomerID != c.CustomerID)   
    select c;

foreach (var c in query) 
    Console.WriteLine( c );
查看更多
琉璃瓶的回忆
5楼-- · 2019-01-01 10:22

For anyone who also wants to use a SQL-alike IN operator in C#, download this package :

Mshwf.NiceLinq

It has In and NotIn methods:

var result = list1.In(x => x.Email, list2.Select(z => z.Email));

Even you can use it this way

var result = list1.In(x => x.Email, "a@b.com", "b@c.com", "c@d.com");
查看更多
浪荡孟婆
6楼-- · 2019-01-01 10:27

One could also use All()

var notInList = list1.Where(p => list2.All(p2 => p2.Email != p.Email));
查看更多
弹指情弦暗扣
7楼-- · 2019-01-01 10:28

I don't know if this will help you but..

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers    
    where !(from o in dc.Orders    
            select o.CustomerID)    
           .Contains(c.CustomerID)    
    select c;

foreach (var c in query) Console.WriteLine( c );

from The NOT IN clause in LINQ to SQL by Marco Russo

查看更多
登录 后发表回答