如何计算LINQ的总工作时间?

时间:2011-03-03 11:20:24

标签: c# linq .net-3.5 linq-to-entities

我有一个表,为每个用户保存时钟输入/输出记录:

RecID   User    In/Out  ClockInOutTime
8      1       IN      25/02/2011 09:36:44
9      1       OUT     25/02/2011 11:36:44
10    1       IN      25/02/2011 12:36:44
11    1       OUT     25/02/2011 17:36:44
12    1       IN      26/02/2011 00:00:00
13    1       OUT     26/02/2011 12:00:00
14    1       IN      26/02/2011 09:00:44
15    1       OUT     26/02/2011 12:36:44

如何使用LINQ计算每个月的总工作时间?

欢呼声

4 个答案:

答案 0 :(得分:2)

  SELECT (SELECT SUM(DATEDIFF(SECOND,[ClockInOutTime], GETDATE()))
     FROM [swp].[dbo].[Table_1] t1
     WHERE [In/Out] = 'IN'
     AND t1.[User] = t.[User]) -
     Coalesce((SELECT SUM(DATEDIFF(SECOND,[ClockInOutTime], GETDATE()))
     FROM [swp].[dbo].[Table_1] t2
     WHERE [In/Out] = 'OUT'
     AND t2.[User] = t.[User]),0)
  FROM [swp].[dbo].[Table_1] t   
  GROUP BY [User]

SQL方法解决这个问题,而不是最好的方法,但即使最后一个事件没有OUT时间戳,即最后一个会话仍然没有关闭时,它也可以工作。

答案 1 :(得分:1)

这在Linq或SQL中都是非常重要的。没有简单的方法将每个OUT记录与SQL中相应的IN记录链接起来。

您有两种选择:

  1. 查询数据并在for循环中计算代码。
  2. 更改表格架构,如:RecID, User, ClockInTime, ClockOutTime
  3. 选项1易于实现,但我会认真考虑选项2.如何在业务规则中定义每个IN记录必须后跟相应的OUT记录(或者最后一个)记录)?

答案 2 :(得分:0)

TimeSpan output = new TimeSpan(0,0,0);
using (var enumerator = input.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
      var begin = enumerator.Current.ClockInOutTime;
      if(!enumerator.MoveNext())
        break;

      var end = enumerator.Current.ClockInOutTime;
      output += (end - begin);
    }
}

是的,它不是LINQ,但我想提供一个解决方案 - 其次,如果日期不是交替的(所以在IN总是OUT之后),它会破坏。

答案 3 :(得分:0)

没有只使用linq的解决方案。这是因为您需要引入错误处理(如果用户忘记注销,通常会有最长时间应用等)。

我会按用户对数据进行分组,按日期时间排序,然后在每个数据中运行,并在每个数据中进行计算。