繁体   English   中英

获取日期期限查询中的最高版本

[英]Get max version within a date period query

我正在尝试编写一个LINQ查询,该查询将获取所有记录并按PeriodSep-18将它们分组,然后返回该周期内具有最高Version号的记录。 例如,如果我的periodNames列表中包含三个句periodNames则输出列表应返回:

  1. Sep-18版本:1、2、3(返回版本3的记录)

  2. Oct-18版本:1、2(返回版本2的记录)

  3. 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

官方还没有定义类的PeriodVersionNumber ,我们知道他们的唯一的事情是,你有一些代码,可以决定两者是否Periods相等,和你有什么事情,你可以决定哪些VersionNumber较大。

IEqualityComparer<Period> periodComparer = ...
IComparer<VersionNumber> versionComparer = ...

如果PeriodDateTime相似,而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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM