簡體   English   中英

我如何.OrderBy()和.Take(x)這個LINQ查詢?

[英]How do I .OrderBy() and .Take(x) this LINQ query?

下面的LINQ查詢工作正常,但我需要對其進行一些調整。

我希望所有recordId所組合文件中的記錄(客戶編號),然后通過排序,按降序排列,日期。 我正在進行分組,日期按降序排列。 現在,調整開始了。

我希望組按recordId升序排列。 目前,似乎按日期對組進行了排序。 我嘗試在.GroupBy之后添加.OrderBy,但根本無法正常工作。

最后,我想。取(x)的記錄,其中x是依賴於一些其他因素。 基本上,。取(X)將返回最近期的X個記錄。 我想在不同的地方放置。取(x)和我沒有得到正確的結果。

var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new 
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderByDescending (m => m.date)
.GroupBy (m => m.recordId)
.Dump();

編輯#1 - 的recordId不是唯一的。 可能/將有多個具有相同recordId的記錄。 recordId實際上是一個客戶編號。

輸出將與姓,名,日期和的recordId一個結果。 根據多個因素,每個recordId返回1至5條記錄。

編輯#2-.Take(x)用於recordId。 每個recordId可以具有多個行。 現在,讓我們假設我想要每個recordId的最新日期。 (按日期降序選擇top(1))

編輯#3 -

以下查詢生成以下結果。 請注意,每個recordId在輸出中僅產生1行(可以),並且它看起來是最近的日期。 我還沒有徹底檢查。

現在,如何按recordId升序排序?

var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new 
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = Convert.ToInt32(tokens[13]),
date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy (m => m.recordId)
.OrderByDescending (m => m.Max (x => x.date ) )
.Select (m => m.First () )
.Dump();


FirstName LastName recordId date 
X      X      2531334      3/11/2011 12:00:00 AM 
X      X      1443809      10/18/2001 12:00:00 AM
X      X      2570897      3/10/2011 12:00:00 AM
X      X      1960526      3/10/2011 12:00:00 AM
X      X      2475293      3/10/2011 12:00:00 AM
X      X      2601783      3/10/2011 12:00:00 AM
X      X      2581844      3/6/2011 12:00:00 AM
X      X      1773430      3/3/2011 12:00:00 AM
X      X      1723271      2/4/2003 12:00:00 AM
X      X      1341886      2/28/2011 12:00:00 AM
X      X      1427818      11/15/1986 12:00:00 AM

您不能輕易按不屬於“分組依據”字段的字段進行排序。 您會獲得每個組的列表。 這意味着,您將獲得每個recordIddate列表。

  • 您可以按最大(日期)或最小(日期)排序。
  • 或者,您可以按recordId和日期分組,並按日期排序。

最近日期排序:

.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
.SelectMany(x => x.First

Take的部分是另外一個問題。 您可以僅將Take(x)添加到表達式中,然后獲得此數量的組。

編輯:

對於一種select top(1)

.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
// take the first of each group, which is the most recent
.Select(x => x.First())
// you got the most recent record of each recordId 
// and you can take a certain number of it.
.Take(x);

之前我在回答中打斷過,根據現在的問題,您將不再需要它:

// create a separate group for each unique date and recordId
.GroupBy (m => m.date, m => m.recordId)
.OrderByDescending (m => m.Key)

只需添加

.OrderBy( g=> g.Key);

分組之后。 這將按RecordId升序排列您的groupings

最后,我想。取(x)的記錄,其中x是依賴於一些其他因素。 基本上,。取(X)將返回最近期的X個記錄。

如果您按日期表示“最新”,那么為什么要首先按RecordId分組-只是按日期降序排列:

..
.OrderByDescending (m => m.date)
.Take(x)
.Dump();

如果您只想按分組確定的順序獲得前x個記錄,則可以執行以下操作:

...
.GroupBy (m => m.recordId)
.SelectMany(s => s)
.Take(x)
.Dump();

這似乎與您的其他問題非常相似- 使用LINQ讀取已刪除的文件

我完全不相信您要在此處使用Group-我相信相反,您想要使用OrderBy和ThenBy-類似:

var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new 
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderBy (m => m.recordId)
.ThenByDescending (m => m.date)
.Dump();

對於簡單的Take ...,您可以僅在Dump()之前添加此.Take(N) Dump()

但是,我不確定這是您要找的東西嗎? 你能澄清你的問題嗎?

如果您想要每個組的前三個,那么我認為您需要使用如下嵌套查詢:

var recipients = File.ReadAllLines(path)
             .Select(record => record.Split('|'))
             .Select(tokens => new
             {
                 FirstName = tokens[2],
                 LastName = tokens[4],
                 RecordId = tokens[13],
                 Date = Convert.ToDateTime(tokens[17])
             }
             )
             .GroupBy(m => m.RecordId)
             .Select(grouped => new 
             {
                 Id = grouped.Key,
                 First3 = grouped.OrderByDescending(x => x.Date).Take(3)
             }
             .Dump();

如果要將其展平到記錄列表中,則可以使用SelectMany:

var recipients = var recipients = File.ReadAllLines(path)
             .Select(record => record.Split('|'))
             .Select(tokens => new
             {
                 FirstName = tokens[2],
                 LastName = tokens[4],
                 RecordId = tokens[13],
                 Date = Convert.ToDateTime(tokens[17])
             }
             )
             .GroupBy(m => m.RecordId)
             .Select(grouped => grouped.OrderByDescending(x => x.Date).Take(3))
             .SelectMany(item => item)
             .Dump();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM