[英]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.