相交LINQ查询

如果我有一个IEAumerable,其中ClassA公开一个types为long的ID属性。 是否有可能使用Linq查询来获取属于第二个IEnumerable的ID的所有ClassA实例?

换句话说,这可以做到吗?

IEnumerable<ClassA> = original.Intersect(idsToFind....)? 

其中original是一个IEnumerable<ClassA> ,idsToFind是IEnumerable<long>

是。

正如其他人所回答的那样,你可以使用Where ,但是对于大集合来说效率会非常低。

如果性能是一个问题,你可以打电话Join

 var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o); 

如果idsToFind可以包含重复项,则需要在ID或结果上调用Distinct() ,或者用idsToFindreplaceJoinGroupJoin的参数相同)。

我将使用Intersect发布答案。

如果要交叉2个相同types的IEnumerables ,这非常有用。

首先我们需要一个EqualityComparer

  public class KeyEqualityComparer<T> : IEqualityComparer<T> { private readonly Func<T, object> keyExtractor; public KeyEqualityComparer(Func<T, object> keyExtractor) { this.keyExtractor = keyExtractor; } public bool Equals(T x, T y) { return this.keyExtractor(x).Equals(this.keyExtractor(y)); } public int GetHashCode(T obj) { return this.keyExtractor(obj).GetHashCode(); } } 

其次,我们将KeyEqualityComparer应用于Intersect函数:

 var list3= list1.Intersect(list2, new KeyEqualityComparer<ClassToCompare>(s => s.Id)); 

你可以做到这一点,但在目前的forms,你要使用Where扩展方法。

 var results = original.Where(x => yourEnumerable.Contains(x.ID)); 

另一方面Intersect会发现在两个IEnumerable的元素。 如果你正在寻找一个ID列表,你可以做以下利用Intersect

 var ids = original.Select(x => x.ID).Intersect(yourEnumerable); 

一个简单的方法是:

 IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID)); 

使用Where方法来筛选结果:

 var result = original.Where(o => idsToFind.Contains(o.ID));