如何使用LINQ避免在Where()子句中调用Contains()?

时间:2016-02-05 19:49:08

标签: c# linq

我有一个非常简单的LINQ表达式:

$window

我认为可能有办法使用class Foo { ... int Id { get; } } IEnumerable<Foo> foos = ...; IEnumerable<int> ids = ...; var remainder = foos.Where(f => !ids.Contains(f.Id)); 和/或remainder和/或Join()生成相同的Intersection()集,但我是不够聪明,不能制定它。

我正在努力使用Join()中的Except(),因为!方面的投影集交集是:

Join()

但我正在寻找逆转。你能帮我吗?谢谢!

1 个答案:

答案 0 :(得分:3)

您在Relational algrebra中寻求的内容称为 Antijoin 。在关系数据库中,它通常使用left outer join(或者 semijoin ,如果我们使用相同的术语)并right支持NULL。 }。最接近的LINQ构造是GroupJoin,其中检查空内组。

以下是查找示例的方式(将其与基于Contains的版本进行比较)

查询语法:

var remainder = from foo in foos
        join id in ids on foo.Id equals id into idGroup
        where !idGroup.Any()
        select foo;

方法语法:

var remainder = foos.GroupJoin(ids, foo => foo.Id, id => id, (foo, idGroup) => new { foo, idGroup })
    .Where(e => !e.idGroup.Any())
    .Select(e => e.foo);