如果我有一个IEnumerable对象,其中ClassA公开了一个类型为long的ID属性。 是否可以使用Linq查询获取所有ID属于第二个IEnumerable对象的ClassA实例?
换句话说,这可行吗?
IEnumerable<ClassA> = original.Intersect(idsToFind....)?
original 是一个 IEnumerable<ClassA>
类型的对象,idsToFind 是一个 IEnumerable<long>
类型的对象。
我将使用Intersect
发布一个答案。
如果您想要对相同类型的2个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));
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));
Join
操作符的扩展方法:private static IEnumerable<TSource> IntersectBy<TSource, TKey>(
this IEnumerable<TSource> source,
IEnumerable<TKey> keys,
Func<TSource, TKey> keySelector)
=> source.Join(keys, keySelector, id => id, (o, id) => o);
var result = items.IntersectBy(ids, item => item.id)
。itemList = _context.Item
.Intersect(itemList)
.Include(i => i.Notes)
.ToList();
现在似乎有效的是:
itemList = _context.Item
.Where(item => itemList.Contains(item))
.Include(i => i.Notes)
.ToList();
这似乎按预期工作,没有任何显著的性能差异,并且与第一个一样简单。
original
或idsToFind
的哪个大小时,使用Join
比Where
/Contains
更有效率?我可以想象对于小列表(也许20-30项),Join
会有太多的开销。 - Tobias