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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:57:23  来源:igfitidea点击:

Intersect LINQ query

c#.netlinq

提问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 idsToFindcan contain duplicates, you'll need to either call Distinct()on the IDs or on the results or replace Joinwith GroupJoin(The parameters to GroupJoin would be the same).

如果idsToFind可以包含重复项,则需要调用Distinct()ID 或结果或替换JoinGroupJoin(GroupJoin 的参数将相同)。

回答by Ahmad Mageed

Use the Wheremethod to filter the results:

使用Where方法过滤结果:

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

回答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 Whereextension method.

您可以这样做,但在当前形式中,您需要使用Where扩展方法。

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

Intersecton 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 IEnumerablesof 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 KeyEqualityComparerto the Intersectfunction:

其次,我们应用KeyEqualityComparerIntersect功能:

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 Joinoperator:

命名事物很重要。这是基于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.

这似乎按预期工作,没有任何显着的性能差异,并且实际上并不比第一个复杂。