我有一个时钟事件列表,我遇到的问题是我不知道该事件是打卡还是打卡。我的班级看起来像这样。
private class TimeClock
{
public string EmployeeID { get; set; }
public DateTime ShiftDate { get; set; }
public DateTime TimeStamp { get; set; }
}
鉴于具体的EmployeeID和ShiftDate,我需要确定他们何时进出。这可以通过简单的<评价。
var allShifts = (from p1 in punches
join p2 in punches
on new { p1.EmployeeID, p1.ShiftDate } equals
new { p2.EmployeeID, p2.ShiftDate }
where p1.TimeStamp < p2.TimeStamp
select new Shift
{
EmployeeID = p1.EmployeeID,
Hours = p2.TimeStamp.Subtract(p1.TimeStamp).TotalHours
}).ToList();
这很有效,但如果一名员工每天不止一次打入和打出,那么这种情况很明显。在那种情况下,我希望看到两个班次,一个用于第一次打入/打出,另一个用于第二个。
我很感激帮助。 井架
答案 0 :(得分:2)
您可以按员工和日期对拳头进行分组。然后,从每个组中,您可以选择打卡和换出对,并计算总小时数的总和:
from p in punches
group p by new { p.EmployeeID, p.ShiftDate } into g
let punch = g.First()
select new Shift
{
EmployeeID = punch.EmployeeID,
FirstName = punch.FirstName,
LastName = punch.LastName,
TimeClockID = punch.TimeClockID,
Hours = g.OrderBy(p => p.TimeStamp)
.Select((p,i) => new {Punch = p, Index = i})
.GroupBy(x => x.Index / 2)
.Select(inOut => new {
PunchInTime = inOut.First().Punch.TimeStamp,
PunchOutTime = inOut.Last().Punch.TimeStamp
})
.Sum(x => x.PunchOutTime.Subtract(x.PunchInTime).TotalHours)
}).ToList();
以下是如何选择进出的对象
{ Punch, Index }
对象上使用打孔对象及其索引在有序的打孔列表中对每组打孔进行投影inOut
是两个匿名对象的分组{ Punch, Index }
)答案 1 :(得分:2)
如果稍微调整Shift模型:
public class TimeClock
{
public int EmployeeId { get; set; }
public int TimeClockId { get; set; }
public DateTime TimeStamp { get; set; }
}
public class Shift
{
public TimeClock PunchIn { get; set; }
public TimeClock PunchOut { get; set; }
public int EmployeeId { get; set; }
public bool HasShiftEnded
{
get { return PunchIn != null && PunchOut != null; }
}
public double? DurationInHours
{
get
{
if (HasShiftEnded)
return (PunchOut.TimeStamp - PunchIn.TimeStamp).TotalHours;
return null;
}
}
}
您可以使用以下LINQ查询:
var shifts = punches
.Where (x => x.EmployeeId == 1 )
.OrderBy (x => x.TimeStamp)
.Select ((x, i) => new { Index = i, Punch = x })
.GroupBy (x => x.Index / 2)
.Select (x => x.Select (v => v.Punch))
.Select (x => new Shift
{
EmployeeId = x.ElementAt(0).EmployeeId,
PunchIn = x.ElementAt(0),
PunchOut = x.ElementAtOrDefault(1)
});
以下是:
以下是您可以试用的complete LINQPad script。