Linq -如何通过'let'赋值和求和'价值

本文关键字:求和 价值 赋值 let Linq 何通过 | 更新日期: 2023-09-27 18:18:14

我正在使用一个API,我无法控制它从SQL服务器返回数据作为List<string>,每个字符串的列以逗号分隔。

这个特定的数据集作为varchardatetime返回,如下所示:

{
    "Prefix_IdentifierA,1/1/1900 12:30:00 AM,", 
    "Prefix_IdentifierA,1/1/1900 12:15:00 AM,", 
    "Prefix_IdentifierB,1/1/1900 01:00:00 AM,", 
    "Prefix_IdentifierB,1/1/1900 12:45:00 AM,"
}

datetime只表示一个时间,因此所有的日期都是相同的。

我需要将其转换为每个标识符的总持续时间的对象集合:

public class Log
{
    public string Identifier { get; set; }
    public int DurationInSeconds { get; set; }
}

所以结果集合应该是这样的:

{
    Log { Identifier = "IdentifierA", DurationInSeconds = 45 },
    Log { Identifier = "IdentifierB", DurationInSeconds = 105 }
}

目前我在2个Linq查询中这样做:

1)从每一行中提取IdentifierDurationInSeconds:

var logs1 = (from row in rows
             select row.Split(',')
             into columns
             let identifier = columns[0].Replace("Prefix_", string.Empty)
             let duration = DateTime.Parse(columns[1])
             let durationInSeconds = duration.Hour * 3600 + duration.Minute * 60 + duration.Second
             select new { Identifier = identifier, DurationInSeconds = durationInSeconds }).ToList();

2)由Identifier和sum DurationInSeconds分组:

var logs2 = (from log in logs1
             group log by log.Identifier
             into grouping
             orderby grouping.Key
             select new Log { Identifier = grouping.Key, DurationInSeconds = grouping.Sum(log => log.DurationInSeconds) }).ToList();

来自第一个查询的匿名类型与Log对象相同,因此是否有任何方法将这2个查询合并为一个?

EDIT: My progress so far

我已经通过identifier分组,但无法找出如何获得durationInSeconds的总和:

var logs = (from row in rows
            select row.Split(',')
            into columns
            let identifier = columns[0].Replace("Prefix_", string.Empty)
            let duration = DateTime.Parse(columns[1])
            let durationInSeconds = duration.Hour * 3600 + duration.Minute * 60 + duration.Second
            group rows by identifier
            into grouping
            select new { Identifier = grouping.Key, DurationInSeconds = grouping.Sum(?????) }).ToList();

Linq -如何通过'let'赋值和求和'价值

您可以通过返回IGrouping<IEnumarable<T>>identifier分组,因此您可以从中获取标识符,这只不过是Key,接下来您可以再次为每个标识符投影IEnumarable并解析那里的duration变量。请注意,分组前不需要存储。

这个查询应该可以正常工作:-

var logs =  (from row in rows
            select row.Split(',') into columns
            let identifier = columns[0].Replace("Prefix_", string.Empty)
            group columns by identifier into g
            select new Log { 
                  Identifier = g.Key, 
                  DurationInSeconds = (from dur in g
                                      let duration = DateTime.Parse(dur[1])
                                      select duration.Hour * 3600 + duration.Minute * 60 
                                              + duration.Second).Sum()
                           }).ToList();

如何将查询语法与方法语法相结合?

(...)select new { Identifier = identifier, DurationInSeconds = durationInSeconds }).GroupBy(l => l.Identifier)(...)