我有两个集合,这两个集合都有属性电子邮件。我需要在第一个列表中获得电子邮件不存在于第二个列表中的项目列表。对于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 };

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


当前回答

您需要使用Except运算符。

var answer = list1.Except(list2);

更好的解释在这里:https://learn.microsoft.com/archive/blogs/charlie/linq-farm-more-on-set-operators

注意:此技术仅适用于基本类型,因为您必须实现一个IEqualityComparer才能对复杂类型使用Except方法。

其他回答

或者你可以这样做:

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

为简单起见,使用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());

对于任何想要在c#中使用类似sql的IN操作符的人,请下载这个包:

Mshwf。NiceLinq

它有In和NotIn方法:

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

你也可以这样用

var result = list1.In(x => x.Email, "a@b.com", "b@c.com", "c@d.com");
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};

如果组为空,就不能做一个外部连接,只从第一个列表中选择项目吗?喜欢的东西:

Dim result = (From a In list1
              Group Join b In list2 
                  On a.Value Equals b.Value 
                  Into grp = Group
              Where Not grp.Any
              Select a)

我不确定这是否会以任何一种有效的方式与实体框架一起工作。