唉,你忘了给我们你的数据库表的结构。您的 EnterTime 和 ExitTime 是完整的 DateTimes,还是您有 WorkDay,以及员工开始和停止工作的那一天的 TimeOfDay?
除了你忘了给我们你的表结构外,我不知道你是如何与你的数据库通信的,是使用实体框架,还是说传统的 SQL,你说的是哪种 SQL 方言。有些方言可以进行 DateTime 计算,有些则没有。
MadReflection 的评论很明智:如果您可以更改数据库,请考虑记住午餐前班次的开始和停止日期时间以及午餐后班次的开始/停止日期时间。这样,您就可以为未来的变化做好准备,例如每位员工的不同午餐时间,甚至是员工每天的不同午餐时间。如果您在 DateTime 中考虑进入和退出,您甚至可以让员工在除夕开始工作并在不同的年份停止工作。
幸运的是,您不必让数据库计算午餐时间,因为您可以在本地计算午餐时间。这比让数据库管理系统计算它们并将结果从 DBMS 传输到本地进程要快。
在本地计算午餐时间只需减去两个 long,这比传输数据所需的代码要快得多。
所以我们不能给你 SQL。您必须自己编写获取数据的过程。
您需要一种方法来获取一段时间内每个员工的 EnterTime / ExitTime ,或者可能是所有员工的。结果是这样的:
class WorkingTimes
{
public EmployeeInformation Employee {get; set;}
public DateTime EnterTime {get; set;}
public DateTime ExitTime {get; set;}
}
以及为每个员工或所有员工获取此信息的方法:
IEnumerable<WorkingTimes> FetchWorkingTimes(DateTime beginPeriod, DateTime endPeriod)
{
...
}
IEnumerable<WorkingTimes> FetchWorkingTimes(int employeeId,
DateTime beginPeriod, DateTime endPeriod)
{
...
}
要将获取的数据转换为您想要的格式,可以使用简单的 LINQ 方法:
class WorkingTimeExt
{
// TODO: if needed: add employee information
public System.DayOfWeek DayOfWeek => this.EnterTime.DayOfWeek;
public DateTime EnterTime {get; set;}
public DateTime ExitTime {get; set;}
public DateTime StartLunch {get; set;}
public DateTime StopLunch {get; set;}
public string Lunch => String.Format("...", this.StartLunch, this.StopLunch);
public TimeSpan WorkingTime => this.StartLunch - this.EnterTime
+ this.ExitTime - this.StopLunch;
}
WorkingTime的计算速度很快,就是一些long的加法。
TimeSpan defaultLunchStart = TimeSpan.FromHours(13.00);
TimeSpan defaultLunchEnd = TimeSpan.FromHours(15.00);
IEnumerable<WorkingTimes> fetchedWorkingTimes = ...
IEnumerable<WorkingTimesExt> result = fetchedWorkingTimes
.Select(fetchedTimes => new WorkingTimesExt
{
EnterTime = fetchedWorkingTimes.EnterTime,
ExitTime = fetchedWorkingTimes.ExitTime,
StartLunchTime = fetchedWorkingTime.EnterTime.Date + defaultLunchStart,
StopLunchTime = fetchedWorkingTime.ExitTime.Data + defaultLunchStop,
});
如果您需要定期执行此操作,请考虑为其创建扩展方法:
IEnumerable<WorkingTimesExt> result = ToExtendedWorkingTimes(
this IEnumerable<WorkingTimes> source,
TimeSpan timeLunchStart,
TimeSpan timeLunchStop)
{
return source.Select(fetchedTimes => new WorkingTimesExt
{
EnterTime = fetchedWorkingTimes.EnterTime,
ExitTime = fetchedWorkingTimes.ExitTime,
StartLunchTime = fetchedWorkingTime.EnterTime.Date + timeLunchStart,
StopLunchTime = fetchedWorkingTime.ExitTime.Data + timeLunchStop,
});
}