【问题标题】:Linq DateTime Difference sumLinq 日期时间差总和
【发布时间】:2017-08-11 14:57:41
【问题描述】:

我有一个分组依据,我想找出两个日期之间的差异,然后将结果添加到最终总和中。但我不断收到无法从时间跨度转换为长的错误。 这是我使用的代码:

var summary = (
  from p in db.CP_SDV_Acc
  where p.Scandate >= start && p.EndDate <= end && p.Device==divice
  let k = new
  {
    //try this if you need a date field 
    //   p.SaleDate.Date.AddDays(-1 *p.SaleDate.Day - 1)
    Device = p.Device,
  }
  group p by k into t
  select new OeeRecovery
  {
    Device = t.Key.Device,

    GoodPcs = t.Sum(p => p.GoodPcs),
    BadPcs=t.Sum(p=>p.BadPcs),
    Oee =(decimal)(t.Sum(p => p.GoodPcs)- t.Sum(p => p.BadPcs)) / t.Sum(p => p.GoodPcs),
    WorkTime = t.Sum(x=>new TimeSpan(x.EndDate-x.Scandate).TotalMilliseconds??TimeSpan.Zero)

    //t.Sum(new TimeSpan( p =>  p.EndDate - p.Scandate))
    //t.Aggregate(TimeSpan.Zero, (total, it) =>total += (it.EndDate-it.Scandate)),
}).ToList();

WorkTimeTimeSpan 类型,EnddatescandateDateTime 类型。
我怎样才能得到时间跨度的总和?

【问题讨论】:

  • 这个带有 null-coalesce 运算符 (??) 的表达式甚至可以编译吗? new 将始终返回一个实例,那么您在这里期望什么?请注意,TotalMillisecondsdoubleTimeSpan.ZeroTimeSpan
  • 我在 (x.EndDate-x.Scandate) 中得到错误
  • 对此的最快修复(只是为了让它不会失败,将 TimeSpan.Zero 更改为 TimeSpan.Zero.TotalMilliseconds。然后 null 合并的两个部分将返回相同的类型,并且那么它将自动装箱为 Long。此外,您不需要新的 TimeSpan,因为减去两个日期值会返回一个 TimeSpan。所以您可以这样做: (x.EndDate-x.ScanDate).TotalMilliseconds??TimeSpan .Zero.Milliseconds,甚至更简单的(x.EndDate-x.ScanDate).TotalMilliseconds??0
  • 您使用的是哪个 EF 版本(EF6 或 EF Core)?
  • 它的 EF6 ,没有更多错误,但是当我尝试获取数据时崩溃了表达。

标签: c# entity-framework linq


【解决方案1】:

这是一项具有挑战性的任务,主要是因为 LINQ to Entities 不支持 DateTimeTimeSpan 的大部分 CLR 方法/属性/运算符。

我看到的唯一解决方案是使用DbFunctions.DiffSeconds 规范函数以秒为单位获取差异,将它们相加,然后使用另一个规范函数DbFunctions.CreateTime 转换为TimeSpan,手动计算小时、分钟和秒数秒:

...
group p by k into t
let workSecs = t.Sum(x => DbFunctions.DiffSeconds(x.Scandate, x.EndDate)) ?? 0
select new OeeRecovery
{
    ...
    WorkTime = DbFunctions.CreateTime(workSecs / 3600, (workSecs / 60) % 60, workSecs % 60)
    ...
}

【讨论】:

  • "从字符串转换日期和/或时间时转换失败。"我在那里看不到任何字符串,它只是在运行时崩溃
  • 我也没有看到。这是您唯一能弄清楚的事情,因为我已经在带有DateTime 字段的示例表上测试了上述构造并且它有效。您可以先注释掉 let workSecs = ...WorkTime = ... 行,看看是否仍然出现运行时异常。
猜你喜欢
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 2017-03-20
  • 2014-01-22
  • 1970-01-01
相关资源
最近更新 更多