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

问题描述:

我有一个表持有时钟输入/输出记录每个用户:如何计算LINQ中的总工作时间?

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每月?

欢呼

+2

首先我试着用TSQL解决它;如果你在TSQL中不能很容易地解决这个问题,那么它可能不适合LINQ。我敢说,但是每次使用'ClockInTime'和'ClockOutTime'的班次会让这更容易... – 2011-03-03 11:23:48

这在Linq或SQL中是不平凡的。没有简单的方法将每条OUT记录与SQL中相应的IN记录相关联。

你有两个选择:

  1. 查询数据和环路内的计算代码。
  2. 改变模式表所示:RecID, User, ClockInTime, ClockOutTime

选项1是容易实现的,但我会认真考虑的选项2.如何,每个IN记录必须跟相应的OUT业务规则定义记录(或是最后的记录)?

+0

如果他们每天进出几次,我将如何管理。我无法为每一个列设置一个列,所以这就是我为什么要这样做的原因,但我知道你的意思:) – scouserider 2011-03-03 11:39:02

+0

@ user583341如果你不想每行调用'shift',就称之为'进入时间段' - 它只是定义了一个时钟输入时钟。至少这两个时间是联系在一起的。 – 2011-03-03 11:42:55

+0

@ user583341:您每次进入时,都会创建一条新记录。每当您退出时,您都会更新最后一条记录。在创建新记录之前,您必须检查ClockOutTime设置为NULL的记录。 – 2011-03-03 11:43:29

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),它会打破。

+0

当然,您需要按照DateTime的UserId和Month部分对数据进行分组,将每组有序的输入/输出时间传递给此函数。 – 2011-03-03 11:29:44

+0

当然 - 我在问题中的例子。尽管如此,获取数据应该很容易。 – Femaref 2011-03-03 11:30:58

+0

这可能是一个问题 - 如果用户忘记检查一天结束它将打破 – scouserider 2011-03-03 11:31:48

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

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

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戳即当最后一个会话仍未关闭工作。

+0

哇,你是一个勇敢的SQL战士。第2步:将其转换为Linq? :-) – 2011-03-03 12:12:02

+0

您可以使用该代码在数据库中创建视图,并将其与EF进行映射,就像表格一样。它会更快。 – Silx 2011-03-03 14:34:27