Как рассчитать общее рабочее время в LINQ? - PullRequest
0 голосов
/ 03 марта 2011

У меня есть таблица, в которой хранятся записи тактирования / выхода для каждого пользователя:

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 ]

2 голосов
/ 03 марта 2011
  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 голос
/ 03 марта 2011

Это нетривиально делать в Linq или SQL.Нет простого способа связать каждую запись OUT с соответствующей записью IN в SQL.

У вас есть два варианта:

  1. Запрос данных и вычисление в коде внутри цикла for.
  2. Изменение схемы таблицы, например: RecID, User, ClockInTime, ClockOutTime

Вариант 1 прост в реализации, но я бы серьезно рассмотрел вариант 2. Как вы определяете в своих бизнес-правилах, что за каждой записью IN должна следовать соответствующая запись OUT (или последняя запись)

0 голосов
/ 03 марта 2011

Нет решения, которое будет использовать только linq. Это связано с тем, что вам также необходимо ввести обработку ошибок (если пользователь забывает выйти из системы, обычно есть максимальное время, которое будет применено, и т. Д.).

Я бы сгруппировал данные по пользователю, упорядочил их по дате и затем проследил бы за ними для каждого и выполнил бы расчет для каждого.

0 голосов
/ 03 марта 2011
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), оно сломается.

...