我想根据一个属性从数据库中选择不同的值,当该属性是 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 得到所有的空项目和所有基于属性的不同项目?
未测试。
var result = query.Where(x => x.Id2 == null || !query.Any(y => y.Id2 == x.Id2 && string.Compare(y.Id1, x.Id1) < 0))
这应该可以得到所有的行 Id2 is null
而只有最小的那一行 Id1
对于每一组 Id2
在你的GroupBy之后,你有一个Group的序列。组的Key是Id2的值。
如果Key(Id2)不是空的,你只想要组中的一个元素,你不关心是哪一个。
如果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());
注意:不会有任何空组,所以结果中没有 "默认 "项。
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);