2017-08-11 134 views
2

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

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类型。
我怎么能得到时间跨度的总和?

+0

确实与空聚结操作者此表达式(''??)甚至编译? 'new'将总是返回一个实例,所以你期望在这里有什么?请注意,'TotalMilliseconds'是一个'double','TimeSpan.Zero'是一个'TimeSpan'。 –

+0

我得到的(x.EndDate-x.Scandate)错误此 – user3399295

+0

最快的修复(只是为了得到它没有失败,将TimeSpan.Zero改变TimeSpan.Zero.TotalMilliseconds。然后,两个空的部分coalese将返回相同的类型,然后它会自动装箱到Long。此外,你不需要新的TimeSpan,因为减去两个日期值会返回一个TimeSpan,所以你可以这样做:(x.EndDate- x.ScanDate).TotalMilliseconds ?? TimeSpan.Zero.Milliseconds,或者更简单(x.EndDate-x.ScanDate).TotalMilliseconds ?? 0 –

回答

0

这是一项具有挑战性的任务,主要是因为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) 
    ... 
} 
+0

“转换失败时,转换日期和/或Ť从字符串输入法。”我没有看到有什么字符串,它只是崩溃在运行时 – user3399295

+0

我没有看到任何。这是你唯一可以弄明白的东西,因为我用'DateTime'字段在样本表上测试了上述构造,并且它可以工作。你可以从'let workSecs = ...'和'WorkTime = ...'这两行注释掉,看看你是否仍然得到运行时异常。 –