Linq To SQL和C#中的时间间隔

时间:2012-06-17 09:30:28

标签: c# linq-to-sql datetime sum

我需要总结工作时间。我有两个字段: 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);
 }

1 个答案:

答案 0 :(得分:4)

您可以在此处使用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)

此外,intDateTime之间没有隐式转换,因此条件三元运算符无法成功。

<强>更新

您可以访问TotalMillisecondsTotalSeconds ... 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