LINQ 根据计数 >1 的另一列获取列
Posted
技术标签:
【中文标题】LINQ 根据计数 >1 的另一列获取列【英文标题】:LINQ get column based on another column having count >1 【发布时间】:2020-12-22 07:39:00 【问题描述】:我正在努力通过使用 Entity Framework Core 从数据库中查询 B 列的重复项来获取 A 列的值。示例:
Column A | Column B
--------------------
A | 1
B | 1
C | 2
D | 2
E | 3
我应该得到输出:
A,B,C,D
我打算用它来填充下拉列表。
我试过了:
Options = _context.table.AsEnumerable()
.GroupBy(s => new s.columnA,s.columnB)
.Where(o => o.columnB.Count() > 1)
.Select(o => new SelectListItem
Value = o.Key.columnA,
Text = o.Key.columnB
.ToList()
【问题讨论】:
你的问题不清楚。无论您使用 o.columnB.Count() > 1 还是 o.columnB > 1,都无法将 A、B、C、D 作为输出。您应该在 columnB 上对数据进行分组,然后检查组元素的计数。@987654325 @ 这能回答你的问题吗? Linq with group by having count @DragandDrop 不,该解决方案仅显示我正在检查重复项的列(在本例中为 columnB)。我需要显示在 B 列中有重复项的 A 列项目。 正如Karan所说,既然要根据columnB获取重复记录,GroupBy语句应该像这样.GroupBy(s=>s.columnB)
,然后,您可以使用SelectMany方法找到子项,@ 987654327@
正确,但是SelectMany()
占用了太多内存。我有一个相当大的数据库。
【参考方案1】:
您只想依靠columnB
,然后才应该使用.GroupBy(s => s.columnB)
。更新您的Where
和Select
,如下所示。
注意需要在其中使用SelectMany
和Select
,因为如果我们使用Select
而不是SelectMany
,它将返回List<List<SelectListItem>>
。 SelectMany
会将其展平并返回 List<SelectListItem>
。
Options = _context.table.AsEnumerable()
.GroupBy(s => s.columnB)
.Where(o => o.Count() > 1)
.SelectMany(o => o.Select(x => new SelectListItem
Value = x.columnA,
Text = x.columnB
))
.ToList();
详细说明 Credits to @Flater from helpful comment.
GroupBy
中的 lambda 本质上是“组标识符”。在问题中,每个组由 A 和 B 列的组合唯一性定义。但根据问题的描述,它需要仅基于 B 列组合事物,目标是专门对事物进行分组 无论 A 列包含什么,因此 A 列不应包含在组的标识符中,因为当遇到不同的 A 列值时,查询不应创建新组。
【讨论】:
这是正确的答案,但我认为它可以从为什么需要更改GroupBy
的小细节中受益:GroupBy
中的 lambda 本质上是“组标识符”。在问题中,每个组由 A 和 B 列的组合唯一性定义。但是 OP 希望仅基于 B 列组合事物,目标是不管 i> 列 A 包含的内容,因此列 A 不应包含在组的标识符中,因为当遇到不同的列 A 值时,查询应该不创建一个新组。
@Flater,感谢您的有用评论。我已根据您的评论更新了答案。【参考方案2】:
所以你有 [ColumnA, ColumnB] 的组合,如果你想要 ColumnA 的所有值,其中有多个 ColumnB。
我的建议是将您的 [ColumnA, ColumnB] 转换为“ColumnB”组,其中所有 ColumnA 都具有此 ColumnB。然后只保留具有多个 ColumnA 的组。
所以在你的例子中:
1,值为 A、B 2,值为 C、D 3,值为 E丢弃第 3 组,因为它只有一个元素,并将结果展平。
我们使用overload of GroupBy that has an elementSelector。 elementSelector 将选择 columnA 作为元素。
var combinationsColumnAColumnB = ...
var result = combinationsColumnB.GroupBy(
// parameter keySelector: make groups with same ColumnB
combination => combination.ColumnB,
// parameter elementselector: put only the ColumnA in each group
combination => combination.ColumnA)
// result: groups of columnB with all columnA that belong to this columnB
// keep only those groups that have more than one element
.Where(group => group.Skip(1).Any()
// and flatten the result:
.SelectMany(group => group);
如果您有以下组合:
A 1
A 2
B 1
C 2
您将获得元素 A 两次。如果您不希望这样,请添加Distinct()
【讨论】:
以上是关于LINQ 根据计数 >1 的另一列获取列的主要内容,如果未能解决你的问题,请参考以下文章