C# 交叉LINQ查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2381049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Intersect LINQ query
提问by Klaus Nji
If I have an IEnumerable where ClassA exposes an ID property of type long. Is it possible to use a Linq query to get all instances of ClassA with ID belonging to a second IEnumerable?
如果我有一个 IEnumerable,其中 ClassA 公开了一个 long 类型的 ID 属性。是否可以使用 Linq 查询来获取 ID 属于第二个 IEnumerable 的 ClassA 的所有实例?
In other words, can this be done?
换句话说,这能做到吗?
IEnumerable<ClassA> = original.Intersect(idsToFind....)?
where original is an IEnumerable<ClassA>
and idsToFind is IEnumerable<long>
.
其中 original 是 an IEnumerable<ClassA>
, idsToFind 是IEnumerable<long>
。
采纳答案by SLaks
Yes.
是的。
As other people have answered, you can use Where
, but it will be extremely inefficient for large sets.
正如其他人所回答的那样,您可以使用Where
,但对于大型集合来说效率极低。
If performance is a concern, you can call Join
:
如果性能是一个问题,您可以致电Join
:
var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o);
If idsToFind
can contain duplicates, you'll need to either call Distinct()
on the IDs or on the results or replace Join
with GroupJoin
(The parameters to GroupJoin would be the same).
如果idsToFind
可以包含重复项,则需要调用Distinct()
ID 或结果或替换Join
为GroupJoin
(GroupJoin 的参数将相同)。
回答by Ahmad Mageed
回答by bruno conde
A simple way would be:
一个简单的方法是:
IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID));
回答by David Pfeffer
You can do it, but in the current form, you'd want to use the Where
extension method.
您可以这样做,但在当前形式中,您需要使用Where
扩展方法。
var results = original.Where(x => yourEnumerable.Contains(x.ID));
Intersect
on the other hand will find elements that are in both IEnumerable
's. If you are looking for just a list of ID's, you can do the following which takes advantage of Intersect
Intersect
另一方面会找到在两者中IEnumerable
的元素。如果您只是在寻找 ID 列表,则可以执行以下操作Intersect
var ids = original.Select(x => x.ID).Intersect(yourEnumerable);
回答by Dragos Durlut
I will post an answer using Intersect
.
我将使用Intersect
.
This is useful if you want to intersect 2 IEnumerables
of the same type.
如果您想将 2IEnumerables
个相同类型相交,这很有用。
First we will need an EqualityComparer
:
首先我们需要一个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();
}
}
Secondly we apply the KeyEqualityComparer
to the Intersect
function:
其次,我们应用KeyEqualityComparer
的Intersect
功能:
var list3= list1.Intersect(list2, new KeyEqualityComparer<ClassToCompare>(s => s.Id));
回答by aloisdg moving to codidact.com
Naming things is important. Here is an extension method base on the Join
operator:
命名事物很重要。这是基于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);
You can use it like this var result = items.IntersectBy(ids, item => item.id)
.
你可以这样使用它var result = items.IntersectBy(ids, item => item.id)
。
回答by Kopfs
I've been tripping up all morning on Intersect, and how it doesn't work anymore in core 3, due to it being client side not server side.
我整个上午都在 Intersect 上绊倒了,它如何在核心 3 中不再工作,因为它是客户端而不是服务器端。
From a list of items pulled from a database, the user can then choose to display them in a way that requires children to attached to that original list to get more information.
从从数据库中提取的项目列表中,用户可以选择以需要儿童附加到原始列表以获取更多信息的方式来显示它们。
What use to work was:
工作的用途是:
itemList = _context.Item
.Intersect(itemList)
.Include(i => i.Notes)
.ToList();
What seems to now work is:
现在似乎有效的是:
itemList = _context.Item
.Where(item => itemList.Contains(item))
.Include(i => i.Notes)
.ToList();
This seems to be working as expected, without any significant performance difference, and is really no more complicated than the first.
这似乎按预期工作,没有任何显着的性能差异,并且实际上并不比第一个复杂。