我想要做的是,如果你在代码中看下面,写一个Linq语句,它将返回ShiftEvents组。组由1.)EmpId定义,2。)EndDate /一个ShiftEvent的时间= StartDate /下一个ShiftEvent的时间
我想创建一个Shift对象,我将ShiftEvents组放在Shift.List< ShiftEvents>。
我有一半写了Linq语句似乎加入了ShiftEvents ..这是我完全失去的分组部分。
class ShiftEvent{
public int EmpId { get; set; }
public string Activity { get; set; }
public string StartDate { get; set; }
public string StartTime { get; set; }
public string EndDate { get; set; }
public string EndTime { get; set; }
}
class Shift{
public List<ShiftEvent> ShiftEvents { get; set; }
public int EmployeeId { get; set; }
public DateTime StartOfShiftDate { get; set; }
public DateTime StartOfShiftTime { get; set; }
public DateTime EndOfShiftDate { get; set; }
public DateTime EndOfShiftTime { get; set; }
}
void Main()
{
List<ShiftEvent> se = new List<ShiftEvent>();
// Group 1
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/21", StartTime="23:00",EndDate="2015/01/21",EndTime="23:30"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/21", StartTime="23:30",EndDate="2015/01/22",EndTime="00:30"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="00:30",EndDate="2015/01/22",EndTime="05:30"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="05:30",EndDate="2015/01/22",EndTime="06:30"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="06:30",EndDate="2015/01/22",EndTime="07:00"});
// Group 2
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="07:15",EndDate="2015/01/22",EndTime="09:00"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="09:00",EndDate="2015/01/22",EndTime="10:00"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="10:00",EndDate="2015/01/22",EndTime="11:00"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="11:00",EndDate="2015/01/22",EndTime="12:00"});
se.Add(new ShiftEvent {EmpId=1, Activity="Test", StartDate="2015/01/22", StartTime="12:00",EndDate="2015/01/22",EndTime="13:00"});
// Group 3
se.Add(new ShiftEvent {EmpId=2, Activity="Test", StartDate="2015/01/22", StartTime="07:15",EndDate="2015/01/22",EndTime="09:00"});
se.Add(new ShiftEvent {EmpId=2, Activity="Test", StartDate="2015/01/22", StartTime="09:00",EndDate="2015/01/22",EndTime="10:00"});
se.Add(new ShiftEvent {EmpId=2, Activity="Test", StartDate="2015/01/22", StartTime="10:00",EndDate="2015/01/22",EndTime="11:00"});
se.Add(new ShiftEvent {EmpId=2, Activity="Test", StartDate="2015/01/22", StartTime="11:00",EndDate="2015/01/22",EndTime="12:00"});
se.Add(new ShiftEvent {EmpId=2, Activity="Test", StartDate="2015/01/22", StartTime="12:00",EndDate="2015/01/22",EndTime="13:00"});
var obj = from s1 in se
join s2 in se
on new {EmpId = s1.EmpId, Date = s1.EndDate, Time = s1.EndTime} equals new {EmpId = s2.EmpId, Date=s2.StartDate, Time = s2.StartTime}
select s1;
var shiftList = new List<Shift>();
foreach(var shiftEvent in obj){
var shift = new Shift();
shift.ShiftEvent.Add(shiftEvent);
shift.EmployeeId = shiftEvent.EmpId;
.......
shiftList.Add(shift);
}
}
任何指针都会很棒!
答案 0 :(得分:2)
您可以从员工对班次事件进行分组开始:
var employeeShifts = _shiftEvents.GroupBy(item => item.EmpId);
然后迭代它们以创建轮班。使用第一个班次事件创建第一个班次。如果下一个班次事件在最后一个班次结束时开始,则更新班次的结束日期。如果存在间隙,请将班次添加到列表中并使用当前班次开始新班次。
这是整个解决方案。它有点乱,因为你把时间信息保存为字符串。
var employeeShifts = _shiftEvents.GroupBy(item => item.EmpId);
List<Shift> shifts = new List<Shift>();
foreach (IGrouping<int, ShiftEvent> employeeShift in employeeShifts)
{
var orderedShiftEvents = employeeShift.Select(item => new { ShiftEvent = item, Interval = item.GetShiftInterval() })
.OrderBy(item => item.Interval.Item1);
Shift currentShift = null;
foreach (var shiftEvent in orderedShiftEvents)
{
if (currentShift == null)
{
currentShift = shiftEvent.ShiftEvent.StartShift(shiftEvent.Interval);
continue;
}
if (currentShift.EndOfShiftDate == shiftEvent.Interval.Item1)
{
currentShift.EndOfShiftDate = shiftEvent.Interval.Item2;
currentShift.ShiftEvents.Add(shiftEvent.ShiftEvent);
}
else
{
shifts.Add(currentShift);
currentShift = shiftEvent.ShiftEvent.StartShift(shiftEvent.Interval);
}
}
shifts.Add(currentShift);
}
我必须使用的扩展方法:
public static class ShiftEventExtensions
{
public static Tuple<DateTime, DateTime> GetShiftInterval(this ShiftEvent shiftEvent)
{
return new Tuple<DateTime, DateTime>(ParseDateTime(shiftEvent.StartDate, shiftEvent.StartTime), ParseDateTime(shiftEvent.EndDate, shiftEvent.EndTime));
}
private static DateTime ParseDateTime(string date, string time)
{
string text = string.Concat(date, " ", time);
DateTime result;
if (DateTime.TryParse(text, out result))
{
return result;
}
throw new ArgumentException("Invalid DateTime", text);
}
public static Shift StartShift(this ShiftEvent shiftEvent, Tuple<DateTime, DateTime> interval)
{
return new Shift
{
EmployeeId = shiftEvent.EmpId,
StartOfShiftDate = interval.Item1,
EndOfShiftDate = interval.Item2,
ShiftEvents = new List<ShiftEvent> { shiftEvent }
};
}
}
我忽略了StartOfShitTime
&amp; EndOfShiftTime
类Shift
中的StartOfShiftDate
属性,因为EndOfShiftDate
&amp; {{1}}足以存储时间信息。
此解决方案还假设班次事件时间没有重叠。