[英]Get max version within a date period query
我正在尝试编写一个LINQ查询,该查询将获取所有记录并按Period
即Sep-18
将它们分组,然后返回该周期内具有最高Version
号的记录。 例如,如果我的periodNames
列表中包含三个句periodNames
则输出列表应返回:
Sep-18
版本:1、2、3(返回版本3的记录)
Oct-18
版本:1、2(返回版本2的记录)
Nov-18
版本:1、2、3、4(具有版本4的返回记录)
这是我到目前为止编写的查询:
var previousStatements = _context.Statements.Where(x => periodNames.Contains(x.Period) &&
x.Version == _context.Statement.Max(y => y.Version)).toList();
如何使它适应以上规范? 谢谢
您可以使用GroupBy
来对语句进行分组,并使用Max
来查找最大值,例如
var previousStatements = _context.Statements.Where(x => periodNames.Contains(x.Period))
.GroupBy(x => x.Period)
.Select(x => new { Period = x.Key, MaxVersion = x.Max(y => y.Version))
.ToList();
上面的代码仅返回期间和最大版本号。 如果需要每个时期的版本号最高的记录,则可以使用以下记录:
var previousStatements = (ctx.Items.Where(x => periodNames.Contains(x.Period))
.GroupBy(x => x.Period)
.ToArray())
.Select(x => x.OrderByDescending(y => y.Version).First())
.ToList();
请注意,上面的代码首先使用对ToArray
的调用将GroupBy查询发送到数据库。 从返回的组中,然后在内存中检索每个期间的最高版本号的行。
尝试使用GroupBy,然后使用orderbydescending获取最大版本号:
_context.GroupBy(f => f.Period).Select(f=>f.OrderByDescending(r=>r.Version).First()).ToList();
我想如果您编写了适当的要求,您就会知道您的解决方案
你写了:
...按时段将它们分组,即Sep-18,然后返回时段内的最高版本号
您的示例未返回最高版本号,而是返回最高版本号的行 ,因此,我们假设这是您想要的:
从报表,集团这些语句与平等的语句组序列
Period
,并从各组,最大的语句返回VersionNumber
。
如果同一期间内的两个语句具有相同的VersionNumber,则尚未定义所需的内容。 假设您认为这种情况不会发生,那么您不必担心在这种情况下会返回哪一个。
因此,您具有一系列Statements
,其中每个Statement
都有一个Period
和一个VersionNumber
。
官方还没有定义类的Period
和VersionNumber
,我们知道他们的唯一的事情是,你有一些代码,可以决定两者是否Periods
相等,和你有什么事情,你可以决定哪些VersionNumber
较大。
IEqualityComparer<Period> periodComparer = ...
IComparer<VersionNumber> versionComparer = ...
如果Period
与DateTime
相似,而VersionNumber
与int相似,则这些比较器很简单,否则您将需要编写比较器。
根据您的要求,代码很简单:
在每个具有此期间的语句组中,仅保留具有最高VersionNumber的语句
IEnumerable<Statement> statements = ... var latestStatementsWithinAPeriod = statements .GroupBy(statement => statement.Period, // group by same value for Period (period, statementsWithThisPeriod) => // From every group of statements keep only the one with the highest VersionNumber // = order by VersionNumber and take the first statementWithThisPeriod .OrderByDescending(statement => statement.VersionNumber, versionComparer) .FirstOrDefault(), periodComparer);
再说一次:如果可以使用默认比较器来确定两个句点何时相等以及哪个VersionNumber较大,则无需添加比较器。
SorBy的缺点是第3个元素和第4个元素等也会排序,而您只需要第一个元素,即第一个具有最大VersionNumber的元素。
这可以通过使用较少使用的Aggregate来优化:
(period, statementsWithThisPeriod) => statementWithThisPeriod.Aggregate(
(newestStatement, nextStatement) =>
(versionComparer.Compare(newestStatement.VersionNumber, nextStatement.VersionNumber) >=0 ) ?
newestStatement :
nextStatement)
这将把第一个语句作为newestStatement(=直到现在这是具有最高版本号的语句)。 第二个元素将放在nextStatement中。 将比较这两个语句,如果nextStatement的VersionNumber大于newestStatement,则nextStatement将被认为是较新的,因此将替换newestStatement。 聚合的结尾将返回newestStatement
您可以尝试使用GroupBy和OrderByDescending,然后选择第一个。
var statements = _context.Statements
.Where(x => periodNames.Contains(x.Period))
.GroupBy(g => g.Period)
.Select(s => s.OrderByDescending(o => o.Version)
.FirstOrDefault()).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.