我需要总结工作时间。我有两个字段: startTime 和 endTime 。是“ 日期时间 ”和“ 可以为空的 ”
我尝试了这个,但它返回错误:
var timeWorked = res.AsEnumerable()
.Sum(f => f.endTime.HasValue ? f.endTime.Value : 0 - f.startTime .HasValue ? f.startTime .Value : 0);
错误:“运营商' - '无法应用于'bool'和'int'类型的操作数”
以上代码位于以下上下文中
try
{
using (serviciosDBDataContext miDataContext = new serviciosDBDataContext("Data Source='xxxxxxx'"))
{
var res = (from p in miDataContext.works
select new
{
p.idWork,
p.status,
p.amount,
p.startTime,
p.endTime
}).ToList();
//HOURS WORKED
var timeWorked = res.AsEnumerable()
.Sum(f => f.endTime.HasValue ? f.endTime.Value : 0 - f.startTime .HasValue ? f.startTime .Value : 0);
}
}
catch (Exception)
{
MessageBox.Show(AppResources.errCargaEstad);
}
答案 0 :(得分:4)
您可以在此处使用GetValueOrDefault和Aggregate方法:
var timeWorked = res.AsEnumerable().Aggregate(TimeSpan.Zero, (total, f) => total + (f.endTime.GetValueOrDefault() - f.startTime.GetValueOrDefault());
在您的示例中,有一个优先级问题,即评估以下内容:
f.endTime.HasValue ? f.endTime.Value : (0 - f.startTime.HasValue)
此外,int
和DateTime
之间没有隐式转换,因此条件三元运算符无法成功。
<强>更新强>
您可以访问TotalMilliseconds
,TotalSeconds
... properties of TimeSpan以在需要数字类型的方法中使用这些值,但是如果您正在处理时间段,则TimeSpan结构是专为此目的而创建的,并且关于代码的mas推理更容易IMO。
更新2
好的,根据你对工作时间的评论,我建议将变量从timeWorked
重命名为hoursWorked
,因为代表名称中没有给出单位的时间的int可能会被误解。您需要的属性是TotalHours。这会返回double
,您可以明确地转换为int
,但可能会丢失精度:
var hoursWorked = (int)res.Sum(f => (f.endTime.GetValueOrDefault() - f.startTime.GetValueOrDefault()).TotalHours);
此外,由于您正在调用ToList
使res
成为列表,因此强制将结果存入内存,因此无需调用AsEnumerable
。