2

我需要总结工作时间。我有 2 个字段:startTimeendTime。是“ datetime ”和“ nullable

我试过了,但它返回错误:

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);
 }
4

1 回答 1

3

您可以在此处使用GetValueOrDefaultAggregate方法:

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此外,an和 a之间没有隐式转换DateTime,因此条件三元运算符不能成功。

更新

您可以访问 TimeSpan 的TotalMilliseconds, TotalSeconds...属性以在需要数字类型的方法中使用这些值,但是如果您正在处理时间段,则 TimeSpan 结构是专门为此目的而创建的,并且更容易对 IMO 进行代码推理。

更新 2

好的,根据您对工作时间的评论,我建议将变量从timeWorkedto重命名,hoursWorked因为表示名称中没有给出单位的时间的 int 可能会被误解。您需要的属性是TotalHours。这将返回 a double,您可以显式转换为 a int,但是可能会丢失精度:

var hoursWorked = (int)res.Sum(f => (f.endTime.GetValueOrDefault() - f.startTime.GetValueOrDefault()).TotalHours);

此外,由于您正在调用ToList创建res列表,这会将结果强制存储到内存中,因此调用 toAsEnumerable是不必要的。

于 2012-06-17T09:33:23.970 回答