簡體   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