c# - LINQ 组合查询

标签 c# .net linq query-optimization

我有两个不同类型的对象集合。让我们称它们为类型 ALPHA 和类型 BRAVO。这些类型中的每一种都有一个属性,即对象的“ID”。类中没有重复的 ID,因此对于任何给定的 ID,最多有一个 ALPHA 和一个 BRAVO 实例。我需要做的是将它们分为 3 类:

  1. ALPHA 中未出现在 BRAVO 集合中的 ID 实例;
  2. BRAVO 中未出现在 ALPHA 集合中的 ID 实例;
  3. 出现在两个集合中的 ID 实例。

在所有 3 种情况下,我都需要手头有集合中的实际对象,以便进行后续操作。

我知道对于第 3 种情况,我可以这样做:

 var myCorrelatedItems = myAlphaItems.Join(myBravoItems, alpha => alpha.Id, beta => beta.Id, (inner, outer) => new
            {
                alpha = inner,
                beta = outer
            });

我还可以为#1 和#2 情况编写代码,看起来像

var myUnmatchedAlphas = myAlphaItems.Where(alpha=>!myBravoItems.Any(bravo=>alpha.Id==bravo.Id));

对于 unMatchedBravos 也是如此。不幸的是,这会导致多次迭代 alpha 集合(可能非常大!),以及多次迭代 bravos 集合(也可能非常大!)。

有什么方法可以统一这些查询概念,从而最大限度地减少对列表的迭代?这些集合可以包含数千个项目。

最佳答案

如果您只对 ID 感兴趣,

var alphaIds = myAlphaItems.Select(alpha => alpha.ID);
var bravoIds = myBravoItems.Select(bravo => bravo.ID);

var alphaIdsNotInBravo = alphaIds.Except(bravoIds);
var bravoIdsNotInAlpha = bravoIds.Except(alphaIds);

如果你想要 alpha 和 bravos 本身,

var alphaIdsSet = new HashSet<int>(alphaIds);
var bravoIdsSet = new HashSet<int>(bravoIds);

var alphasNotInBravo = myAlphaItems
                       .Where(alpha => !bravoIdsSet.Contains(alpha.ID));

var bravosNotInAlpha = myBravoItems
                       .Where(bravo => !alphaIdsSet.Contains(bravo.ID));

编辑: 其他一些选项:

  1. ExceptBy method来自 MoreLinq .
  2. Enumerable.ToDictionary方法。
  3. 如果两种类型都继承自一个通用类型(例如 IHasId 接口(interface)),您可以编写自己的 IEqualityComparer<T>执行; Enumerable.Except has an overload接受相等比较器作为参数。

关于c# - LINQ 组合查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4098176/

相关文章:

c# - 需要一种不显眼的日志记录方法

c# - 如何使用 sql 参数进行选择查询?

c# - 如何以编程方式检索 Excel 工作表中的页数?

c# - 在构造函数中更改扩展的 RichTextBox 文本不起作用

c# - 使用LINQ取前100名和后100名?

c# - LINQ 中的多级分组?

c# - VS2010 不会在 64 位版本的 Windows 上的 WinForms 应用程序中显示未处理的异常消息

c# - 将以编程方式生成的 DataGridTextColumn 的 Visibility 属性绑定(bind)到复选框

.net - 在 docker 容器中运行标准的 .NET 控制台应用程序

c# - 在 C# 中使用 LINQ 读取 Xml 文件