c# - 具有空值的 C# IQueryable LINQ Group By
问题描述
我想根据一个属性从数据库中选择不同的值,并在该属性为null
. IDs
在我的数据库中是Strings
我的数据库如下所示:
Id1 Id2 Value
____________________
1 null Value1
2 1 Value2
3 1 Value3
4 null Value4
5 null Value5
6 2 Value6
7 2 Value7
8 2 Value8
我想从我的查询中得到这样的输出:
Id1 Id2 Value
____________________
1 null Value1
2 1 Value2 // i dont care which one from Id2 = 1 i get
4 null Value4
5 null Value5
6 2 Value6 // i dont care which one from Id2 - 2 i get
如您所见,我想获得一个List
所有元素都Id2
为空的元素,并且只返回一个Id2
相同的元素(我不在乎哪个元素查询将返回)。
我试图编写一些代码:
query
.Where(x => !string.IsNullOrEmpty(x.Id2))
.GroupBy(z => z.Id2)
.Select(grp => grp.FirstOrDefault())
.ToListAsync();
但我没有得到我想要的,只有一个项目表示Id2
,只有一个null
值,像这样:
Id1 Id2 Value
____________________
1 null Value1
2 1 Value2 // I want to get all elements where Id2 = null
6 2 Value6 // and distinct elements based on Id2
我的问题是,如何向 EF 编写查询以获取所有空项目和所有基于属性的不同项目?
解决方案
在您的 GroupBy 之后,您有一个组序列。该组的 Key 是 Id2 的值。
如果 Key (Id2) 不为 null,则您只需要组中的一个元素,而不关心哪个元素。
如果 Key 等于 null,则需要该组的所有元素。
有两种方法可以做到这一点:
- 对所有非空元素执行 GroupBy
- 将它与空元素连接起来
或者:
- 使用 GroupBy 的参数 ResultSelector 来检查 Key 是否为空,可以只选择一个元素,也可以选择该组的所有元素
连接方法
IQueryable<MyClass> source = dbContext....
// the elements with non-null Id2, keep only one element:
IQueryable<MyClass> filledId2 = source
.Where(item => item.Id2 != null)
.GroupBy(item => item.Id2,
// Parameter ResultSelector, take Id2 (key) and all items with this Id2
// to make one new:
(key, itemsWithThisKey) => itemsWithThisKey.FirstOrDefault());
注意:不会有任何空组,因此结果中没有“默认”项目。
具有 null Id2 的元素:
IQueryable<MyClass> emptyId2 = source.Where(item => item.Id2 == null);
连接:
var result = filledId2.Concat(emptyId2);
注意:尚未执行任何查询。如果需要,您可以创建一个大的 LINQ 语句。这不会提高效率。然而,它会降低可读性。
结果参数方法
IQueryable<MyClass> filledId2 = source.GroupBy(item => item.Id2,
// resultSelector: if the key is null, select all elements of the group
// otherwise select a sequence of one element of the group
(key, itemsWithThisKey) => (key == null) ?
itemsWithThisKey : itemsWithThisKey.Take(1))
// result: a sequence of sequences of MyClass objects
// use SelectMany to make it one sequence of MyClass objects:
.SelectMany(group => group);
推荐阅读
- python - 对 pandas 数据框中的浮点数据类型应用 if else 循环
- amazon-web-services - cloudformation 部署能力_auto_expand
- sql - 如何获取一些项目,然后删除重复的项目?
- cakephp-4.x - Cakephp 4.x Admin Authentication 需要重复的控制器吗?
- python-3.x - 如何通过 API 接受 Github 仓库邀请?
- c++ - Eigen 自定义表达式类型(或 CWise Op 仿函数?)
- c++ - 计算不会显示在输出中
- laravel - Laravel 内置身份验证系统中的“登录”和“注册”链接是如何添加到现有页面的?
- reactjs - 两个非常相似的函数,一个不能正确更新状态
- asp.net - Blazor WebSocket 已关闭,状态码为 1006