如何使用Linq To Sql来计算一天中的空闲工作时间?

问题描述:

例如,我有一个任务MIS,所述数据为:如何使用Linq To Sql来计算一天中的空闲工作时间?

ID用户任务TaskStartTime TaskFinishTime

1麦克TASK1 2009-07-28 9点00分○○秒2009-07-28 9点45: 00

2麦克TASK2 2009-07-28九点30分00秒2009-07-28 9时40分00秒

3麦克TASK3 2009-07-28九点50分00秒2009-07-28 10:30:00

4 Mike task4 2009-07-28 10:20:00 2009-07-28 10:30:00

5迈克任务5 2009-07-28 10:40:00 2009-07-28 11:50:00

我如何使用LINQ to SQL中来清点的空闲时段每天如2009年-07-28?

结果应该是:

5分钟(之间任务1,任务2和TASK3)+10分钟

= 15分钟(task4和任务5之间)

+1

这听起来像一个家庭作业的问题,你有没有给你自己解决它一个体面的尝试证据-1。 – 2009-07-28 22:52:32

下面是一些使用Linq来完成工作的代码。我不知道它是否以您正在寻找的形式出现,但逻辑适用于您提供的数据。你应该能够重新排列它为你的应用程序的正确形状。

改进

var rows = new[] { 
    new { Id = 1, Name="Mike", TaskName="task1", StartTime=DateTime.Parse("2009-07-28 09:00:00"), EndTime=DateTime.Parse("2009-07-28 09:45:00") }, 
    new { Id = 2, Name="Mike", TaskName="task2", StartTime=DateTime.Parse("2009-07-28 09:30:00"), EndTime=DateTime.Parse("2009-07-28 09:40:00") }, 
    new { Id = 3, Name="Mike", TaskName="task3", StartTime=DateTime.Parse("2009-07-28 09:50:00"), EndTime=DateTime.Parse("2009-07-28 10:30:00") }, 
    new { Id = 4, Name="Mike", TaskName="task4", StartTime=DateTime.Parse("2009-07-28 10:20:00"), EndTime=DateTime.Parse("2009-07-28 10:30:00") }, 
    new { Id = 5, Name="Mike", TaskName="task5", StartTime=DateTime.Parse("2009-07-28 10:40:00"), EndTime=DateTime.Parse("2009-07-28 11:50:00") }, 
     }; 

var ranges = rows.Select(x => new { StartTime = x.StartTime, EndTime = x.EndTime }); 
int rangeCount = 0; 
while (ranges.Count() != rangeCount) 
{ 
    rangeCount = ranges.Count(); 
    ranges = ranges.Select(x => new { 
     StartTime = ranges.Where(y => (y.StartTime <= x.StartTime && y.EndTime >= x.StartTime) || (y.StartTime <= x.EndTime && y.EndTime >= x.EndTime)).Min(y => y.StartTime), 
     EndTime = ranges.Where(y => (y.StartTime <= x.StartTime && y.EndTime >= x.StartTime) || (y.StartTime <= x.EndTime && y.EndTime >= x.EndTime)).Max(y => y.EndTime), 
    }).Distinct().ToList(); // ToList required to avoid recursion issues 
} 

TimeSpan gapTime = ranges.Max(x => x.EndTime) - ranges.Min(x => x.StartTime) - new TimeSpan(ranges.Sum(x => (x.EndTime - x.StartTime).Ticks)); 

System.Diagnostics.Trace.WriteLine(gapTime); 

像这样

假设您有一组任务对象:

public class Task 
{ 
    public Guid ID { get; set; } 
    public string User { get; set; } 
    public string Task { get; set; } 
    public DateTime TaskStartTime { get; set; } 
    public DateTime TaskFinishTime { get; set; } 
} 

var tasks = new List<Task>(); 
// Fill tasks here... 

var idleTimeInMinutes = 
    tasks.Last().TaskFinishTime.Subtract (tasks.First().TaskStartTime).Minutes 
    - tasks.Sum (t => t.TaskFinishTime.Subtract (t.TaskStartTime).Minutes); 

编辑:现在,等等,我看到您的示例中的任务重叠。然后我写的是不会工作的。我将不得不考虑它...

好的,我已经制定了一个可行的选项。

您可以使用此:

from a in Tasks 
join b in Tasks on true equals true 
where a.TaskStartTime < b.TaskFinishTime 
where a.TaskFinishTime > b.TaskStartTime 
where a.Id < b.Id 
select new { 
    Id = a.Id, 
    User = a.User, 
    Task = (a.Task + " + " + b.Task), 
    TaskStartTime = (a.TaskStartTime < b.TaskStartTime ? a.TaskStartTime : b.TaskStartTime), 
    TaskFinishTime = (a.TaskFinishTime > b.TaskFinishTime ? a.TaskFinishTime : b.TaskFinishTime) 
} 

到了崩溃下的各个任务,直到没有交叉点,那么就采取所有时间的总和,减去的时间在所有任务的总和。

+0

谢谢。我在等你的好消息。 – Mike108 2009-07-28 13:42:02

+0

如果task1是:start = 2009-07-28 09:00:00 end = 2009-07-28 09:51:00结果有问题。 – Mike108 2009-07-28 14:12:36

将有趣的记录拉入内存并在那里处理它们(通过将重叠范围折叠成单个范围)。崩溃任务不适合查询方法,如sql或linqtosql。