C# 使用LINQ的不同日期
我有一个时间表条目列表,通常每个用户在同一天会有多个条目,因为他们在午餐时间打卡进出 我的时间表课程如下所示:C# 使用LINQ的不同日期,c#,linq,C#,Linq,我有一个时间表条目列表,通常每个用户在同一天会有多个条目,因为他们在午餐时间打卡进出 我的时间表课程如下所示: public class TimeSheetEntry { public Guid EmployeeId { get; set; } public DateTime ClockInTimeStamp { get; set; } public DateTime ClockOutTimeStamp { get; set; } } context.TimeSheet
public class TimeSheetEntry
{
public Guid EmployeeId { get; set; }
public DateTime ClockInTimeStamp { get; set; }
public DateTime ClockOutTimeStamp { get; set; }
}
context.TimeSheetEntries.Select(e => e.ClockInTimeStamp.Date).Distinct();
我想确定用户工作的天数。我想通过计算我的列表()
中的唯一天数,使用ClockInTimeStamp
属性来完成此操作
如何使用LINQ获取此列表中的唯一天数?.Distinct()可能就是您想要的。只需指定使用Distinct()对哪个属性进行筛选
.Distinct()可能就是您要查找的内容。只需指定使用Distinct()对哪个属性进行筛选
你是想严格计算日期而不考虑时间吗?如果是这样,您可能希望查看更改两个DateTime属性类型并使用库,它具有仅日期类型
鉴于您对我对您的OP的评论的回应,我强烈建议您远离DateTime,看看野田时间。您是否希望严格计算日期,而不考虑时间?如果是这样,您可能希望查看更改两个DateTime属性类型并使用库,它具有仅日期类型
timesheetEntries
.GroupBy( te => te.EmployeeId )
.Select(
grp => new {
EmployeeId = grp.Key,
DayCount = grp
.Select( te => te.ClockInTimeStamp.Date )
.Distinct()
.Count()
}
)
.ToDictionary(
t => t.EmployeeId,
t => t.DayCount
);
考虑到你对我对你的评论的回应,我强烈建议你远离DateTime,看看Noda Time
timesheetEntries
.GroupBy( te => te.EmployeeId )
.Select(
grp => new {
EmployeeId = grp.Key,
DayCount = grp
.Select( te => te.ClockInTimeStamp.Date )
.Distinct()
.Count()
}
)
.ToDictionary(
t => t.EmployeeId,
t => t.DayCount
);
我意识到中间Select
可以省略:
timesheetEntries
.GroupBy( te => te.EmployeeId )
.ToDictionary(
grp => grp.Key /* EmployeeId */,
grp => grp
.Select( te => te.ClockInTimeStamp.Date )
.Distinct()
.Count()
);
我意识到中间Select
可以省略:
timesheetEntries
.GroupBy( te => te.EmployeeId )
.ToDictionary(
grp => grp.Key /* EmployeeId */,
grp => grp
.Select( te => te.ClockInTimeStamp.Date )
.Distinct()
.Count()
);
由于时间部分的原因,您可能无法区分日期时间。您应该能够通过以下方式获取
DateTime.Date
,从而实现这一点:
public class TimeSheetEntry
{
public Guid EmployeeId { get; set; }
public DateTime ClockInTimeStamp { get; set; }
public DateTime ClockOutTimeStamp { get; set; }
}
context.TimeSheetEntries.Select(e => e.ClockInTimeStamp.Date).Distinct();
注意:如果这是通过EF直接从sql中提取LINQ,则“.Date”部分可能会有问题,因此您可能必须在该部分之前的某个时间强制集合枚举。由于时间部分的原因,您可能无法区分日期时间。您应该能够通过以下方式获取
DateTime.Date
,从而实现这一点:
public class TimeSheetEntry
{
public Guid EmployeeId { get; set; }
public DateTime ClockInTimeStamp { get; set; }
public DateTime ClockOutTimeStamp { get; set; }
}
context.TimeSheetEntries.Select(e => e.ClockInTimeStamp.Date).Distinct();
注意:如果这是通过EF直接从sql中提取LINQ,则您可能对“.Date”部分有一些问题,因此您可能必须在该部分之前的某个时间强制集合枚举。有两个细节我在其他答案中没有说明:
HashSet
中,这将消除重复
然后,如果开始日期和结束日期之间至少有一整天,则循环遍历该范围内的日期并添加所有日期
public static class TimeSheetCalculations
{
public static int CalculateDistinctDays(this IEnumerable<TimeSheetEntry> entries)
{
var uniqueDays = new HashSet<DateTime>();
foreach (var entry in entries)
{
var clockInDate = entry.ClockInTimeStamp.Date;
var clockOutDate = entry.ClockOutTimeStamp.Date;
uniqueDays.Add(clockInDate);
uniqueDays.Add(clockOutDate);
var totalDays = (clockOutDate - clockInDate).TotalDays;
if (totalDays < 2) continue;
for (var x = 1; x < totalDays; x++)
{
uniqueDays.Add(clockInDate.AddDays(x));
}
}
return uniqueDays.Count;
}
}
如果有人在1/1打孔,在1/5打孔,在1/5打孔,在1/6打孔,在1/7打孔,那就是7天,即使他们从来没有在1/2、1/3或1/4打孔
单元测试确认了预期结果
我要检查的另一个错误条件是确认打卡时间在打卡之后。但我不会在这里这么做。我会在其他地方验证该条目(您可能已经验证过了)。我在其他答案中没有看到两个细节:
HashSet
中,这将消除重复
然后,如果开始日期和结束日期之间至少有一整天,则循环遍历该范围内的日期并添加所有日期
public static class TimeSheetCalculations
{
public static int CalculateDistinctDays(this IEnumerable<TimeSheetEntry> entries)
{
var uniqueDays = new HashSet<DateTime>();
foreach (var entry in entries)
{
var clockInDate = entry.ClockInTimeStamp.Date;
var clockOutDate = entry.ClockOutTimeStamp.Date;
uniqueDays.Add(clockInDate);
uniqueDays.Add(clockOutDate);
var totalDays = (clockOutDate - clockInDate).TotalDays;
if (totalDays < 2) continue;
for (var x = 1; x < totalDays; x++)
{
uniqueDays.Add(clockInDate.AddDays(x));
}
}
return uniqueDays.Count;
}
}
如果有人在1/1打孔,在1/5打孔,在1/5打孔,在1/6打孔,在1/7打孔,那就是7天,即使他们从来没有在1/2、1/3或1/4打孔
单元测试确认了预期结果
我要检查的另一个错误条件是确认打卡时间在打卡之后。但我不会在这里这么做。我会在其他地方验证该条目(您可能已经验证过了)。您尝试过什么?您看过
Distinct
linq方法吗?它是谷歌上最热门的“linq distinct”之一,我怀疑它可能对你有用……是的,我有,但它没有返回准确的结果。这可能是因为我处理的是DateTime
,而不仅仅是date。我现在通过转换我的DateTime再次尝试<