我有两个集合,这两个集合都有属性电子邮件。我需要在第一个列表中获得电子邮件不存在于第二个列表中的项目列表。对于SQL,我只会使用“not in”,但我不知道在LINQ中等价。怎么做呢?

到目前为止,我有一个连接,比如。

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

但我不能加入,因为我需要的差异和连接将失败。我需要一些方法使用包含或存在我相信。我只是还没有找到这样做的例子。


当前回答

为简单起见,使用int类型List的示例。

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());

其他回答

我不知道这是否对你有帮助,但是…

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 );

从LINQ中的NOT IN子句到SQL的Marco Russo

你可以使用Where和Any的组合来查找not in:

var NotInRecord =list1.Where(p => !list2.Any(p2 => p2.Email  == p.Email));

在第一个列表中,电子邮件在第二个列表中不存在。

from item1 in List1
where !(list2.Any(item2 => item2.Email == item1.Email))
select item1;

对于那些从一组内存对象开始并对数据库进行查询的人来说,我发现这是最好的方法:

var itemIds = inMemoryList.Select(x => x.Id).ToArray();
var otherObjects = context.ItemList.Where(x => !itemIds.Contains(x.Id));

这就产生了一个很好的WHERE…SQL中的IN(…)子句。

或者你可以这样做:

var result = list1.Where(p => list2.All(x => x.Id != p.Id));