C#Linq使用带并集的distinct
我在db中有一个表,如下所示:C#Linq使用带并集的distinct,c#,linq,C#,Linq,我在db中有一个表,如下所示: Id Name Stream Version UId Tab Key Value CreatedOn CreatedBy 1 Name1 GOP 1 U1 Tab1 co 1 07/01/2018 S, Adam 2 Name1 GOP 1 U2 Tab1 co 1 07/03/2018 S, Adam 3 Name1
Id Name Stream Version UId Tab Key Value CreatedOn CreatedBy
1 Name1 GOP 1 U1 Tab1 co 1 07/01/2018 S, Adam
2 Name1 GOP 1 U2 Tab1 co 1 07/03/2018 S, Adam
3 Name1 GOP 1 U3 Tab2 st 2 07/03/2018 S, Adam
4 Name1 GOP 2 OR Tab1 co 1 07/02/2018 P, Silver
5 Name2 GOP 1 OR Tab1 co 1 07/02/2018 P, Silver
6 Name3 GOP 0 OR1 Tab0 coe 1 07/02/2018 S, Adam
7 Name3 GOP 0 OR2 Tab1 coe 1 07/02/2018 S, Adam
8 Name2 LNT 3 NE Tab1 st 4 07/01/2018 P, Silver
9 Name2 LNT 3 NE1 Tab1 co 2 07/01/2018 P, Silver
10 Name2 LNT 2 NE2 Tab1 st 3 07/01/2018 P, Silver
11 Name2 LNT 0 NE Tab9 co 5 07/01/2018 R, Henry
12 Name3 TTE 0 TT Tab1 ee 2 07/02/2018 R. Henry
13 Name3 TTE 0 T1 Tab1 ee 2 07/02/2018 R. Henry
我想编写一个查询,该查询将为我提供集合的最高版本以及不同的版本0
为此,我将查询编写为,但这没有得到我想要的输出:
var data = response.GroupBy(x => new { x.Name, x.Stream })
.SelectMany(g => g.OrderByDescending(row => row.Version).Take(1)) //This gives highest version
.Union(response.Where(x => int.Parse(x.Version) == 0)) // This gives version 0
.OrderByDescending(o => o.CreatedOn).ToList();
用户界面上所需的输出
Id Name Stream Version CreatedOn CreatedBy
4 Name1 GOP 2 07/02/2018 P, Silver //This is shown as 2 is the highest version for Name1 & GOP combination
5 Name2 GOP 1 07/02/2018 P, Silver //This is shown as Name & Stream combination is different
6 Name1 GOP 0 07/02/2018 S, Adam //Version 0 is always shown - Combination of Name & Stream may or may not have more than one 0 version
8 Name2 LNT 3 07/01/2018 P, Silver //This is shown as 3 is the highest version for Name2 & LNT combination
11 Name2 LNT 0 07/01/2018 R, Henry //Version 0 is always shown
12 Name3 TTE 0 07/02/2018 R, Henry //Version 0 is always shown
在UI上,我试图只显示一个集合的精简版本。当用户单击该集合时,我将显示集合中所有单个集合的详细信息
现在我只想知道如何更新我的查询以便得到我想要的结果
----更新---
var set1 = response.GroupBy(x => new { x.Name, x.Stream})
.SelectMany(g => g.OrderByDescending(row => row.Version).Take(1))
.Where(x => int.Parse(x.Version) != 0).ToList();
var set2 = response.GroupBy(x => new { x.Name, x.Stream, x.Version})
.Select(g => g.First())
.Where(x => int.Parse(x.Version) == 0).ToList();
var setmerged = set1.Union(set2).OrderByDescending(o => o.CreatedOn).ToList();
现在我要做的是个人列表:
var data1 = response.GroupBy(x => new { x.Name, x.Stream})
.SelectMany(g => g.OrderByDescending(row => row.Version).Take(1))
.Where(x => int.Parse(x.Version) != 0)
.OrderByDescending(o => o.CreatedOn).ToList();
上面给出了给定名称和流的所有最新版本
var data2 = response.GroupBy(x => new { x.Name, x.Stream})
.Select(g => g.First())
.Where(x => int.Parse(x.Version) == 0)
.OrderByDescending(o => o.CreatedOn).ToList();
上面给出了给定名称和流的所有0版本
var data2 = response.GroupBy(x => new { x.Name, x.Stream})
.Select(g => g.First())
.Where(x => int.Parse(x.Version) == 0)
.OrderByDescending(o => o.CreatedOn).ToList();
我认为这些单独的列表目前运行良好,但是如何合并它们
是否有一种方法将这些列表连接/合并在一起,以便只返回单个集合。或者,如果有办法将这两个linq查询合并在一起
---更新-----
通过上面的方法使其正常工作,但不确定这是否是一种干净的解决方案。错误使用DISTINCT 这没有道理
DISTINCT
用于过滤重复的行,它们不是重复的行,因为只有版本号相同。DBS应该从哪里知道应该使用哪个CreatedOn
值
更好的解决方案
您需要使用
groupby
,以便使用相同的版本值对所有内容进行分组。请注意,您需要在其他列上使用聚合函数,如MAX()
,以便正确使用它。因此,从更新问题的外观来看,您需要每个不同版本、名称和流的顶部
根据您提供的数据集和所需的结果集,无需对0版本执行任何特殊操作,因为获取不同版本的条件也应包括0版本
您还没有真正指定版本的顺序,所以现在我假设最近更新的版本就是您想要的版本
response.GroupBy(x => new { x.Name, x.Stream, x.Version })
.SelectMany(g => g.OrderByDescending(row => row.CreatedOn).Take(1))
.ToList();
可能还喜欢上面的一行:
.Union(response.Where(x=>int.Parse(x.Version)==0)。Take(1))
?不,这样我就根本得不到0版本。结果只是版本2。我无法复制你的测试。使用.Take(1)
我得到了您想要的结果。您为什么不进行两次查询?@user1563677您更新的解决方案现在很好。但不要在前两个集合中使用ToList()。它将在实际数据库上执行已经存在的命令,因此UNION操作将由您的程序处理。只在setmerged行中使用。小问题,找不到OrderByAscending?我的错误是我更新了伪代码,您只需要使用orderby@user1563677让我知道,这应该可以解决您的问题。不知道查询是否有效,它的构造方式有一些错误。我会在今天晚些时候检查它,并让你知道。我已经更新了我的查询,以显示我试图实现的更详细的解释。