使用linq在可观察的集合中添加timeinterval

时间:2019-02-25 11:37:48

标签: c# wpf linq

我正在通过将sql查询转换为linq来学习Linq。我有一张有时间间隔的桌子。我要添加时间间隔

输入:

Total Time

00:00:14 
00:00:55 
00:00:40

输出:

Total TIme Taken

00:01:49

我用来将上述输入转换为输出的sql查询

     SELECT count(*) as total_claimCount, 
     CONVERT(VARCHAR(10),SUM(DATEDIFF(second, '0:00:00', [Total Time])) /3600) + ':' 
     + RIGHT('00'+CONVERT(VARCHAR(2),(SUM(DATEDIFF(second, '0:00:00', [Total Time])) 
     %3600)/60),2)  + ':' +  RIGHT('00'+CONVERT(VARCHAR(2),SUM(DATEDIFF(second, 
    '0:00:00', [Total Time]))
     %60),2) AS Total_time_taken  FROM dbo.[opcod Audit Information] 
     where [End Time] is not null 

现在,我想在linq中转换以上查询。我已将表数据存储到名为ModelclassTable的可观察集合中。

谢谢。

编辑:表格数据

其中所有列的数据类型均为varchar。

enter image description here

2 个答案:

答案 0 :(得分:2)

我相信这足够了。

给出表名 Table ,列名 TotalTime

TimeSpan ts = new TimeSpan(Table.Select(x => TimeSpan.Parse(x.TotalTime).Ticks).Sum());

ts对象将包含值的总和。

尽管很多其他人指出,长期解决方案绝对不能将Time值存储为varchar。

答案 1 :(得分:1)

将日期/时间信息存储为varchar也许不是很明智。因此,您应该考虑使用datetime列类型。另外,您也许应该使用OR映射器(例如EntityFramework)与数据库进行交互,这样就不必麻烦有关SQL安全性的详细信息了。

尽管如此,给出的还是字符串对列表,它们代表事件的开始时间和日期时间:

public class EventData
{
    public string Start { get; set; }
    public string End { get; set; }

    public TimeSpan CalculateDuration()
    {
        if (String.IsNullOrEmpty(Start)
           || String.IsNullOrEmpty(End))
        {
            // What should happen, if start or end is not set?
        }

        // What should happen, if parsing fails?
        var start = DateTime.Parse(Start);
        var end = DateTime.Parse(End);

        // What should happen, if start is later then end??
        return end - start;
    }

    public override string ToString()
    {
        return $"{Start} - {End} => {CalculateDuration()}";
    }
}

private static readonly Random random = new Random();

private static EventData CreateSample()
{
    var now = DateTime.UtcNow;
    var start = now.AddSeconds(random.Next(1000));
    var end = start.AddSeconds(random.Next(1000));

    return new EventData
    {
        Start = start.ToString(),
        End = end.ToString()
    };
}

有了这些助手,我们现在可以很容易地计算出总和:

private static void Main(string[] args)
{
    var someEvents = Enumerable
        .Range(1, 10)
        .Select(_ => CreateSample())
        .ToList();

    foreach (var item in someEvents)
    {
        Console.WriteLine(item);
    }

    // Here we calculate the sum, by using .Aggregate()
    var all = someEvents.Aggregate(TimeSpan.Zero, (sum, item) => sum + item.CalculateDuration());
    Console.WriteLine(all);

    Console.WriteLine("Finished");
    Console.ReadKey();
}

最后但并非最不重要的: 此代码示例实际上只是一个示例。用这种方式存储和使用值有很多错误(例如,将日期存储为字符串,每次都计算持续时间,不仅一次,不进行参数检查,不进行异常处理等)。因此,请继续学习并尝试找出您的代码和我的示例中的所有错误。希望在几个月后,您将看到此代码并以同样的方式思考。尝试找出如何使用诸如EF或Dapper之类的东西,然后在最后一步,您可以开始考虑LINQ。