2015-11-24 38 views
0

我被困在编写LINQ查询来计算在X天前或同一天创建的项目。LINQ统计在X天前或同一天创建的项目

我有以下表Items

id dateline (timestamp) lastactivity status 
----------------------------------------------------- 
1 1448395260   1448395260 done  
2 1448308860   1448308999 in_progress 
3 1448308860   1448395260 done 
4 1448222460   1448395260 done 
5 1448395260   1448395260 in_progress 

我想写LINQ查询来获取的数量创建并每天现有IN_PROGRESS项目为过去X天。
如果是dateline <= DAY_END (23:59:59) AND (status != 'done' OR lastactivity >= DAY_START (00:00:00)),则会计入物品。
如果项目的日期小于特定日期并且当天关闭,则必须计算在内。

根据上述表格中的项目,预期结果应该是这样的:(对于day值我花了DAY_END时间戳)

day   not_done_items_count 
----------------------------------- 
1448409599 5 
1448323199 3 
1448236799 1 

我现在的LINQ查询看起来是这样的:

var itemsPerDay = (from item in items 
        from i in Enumerable.Range(0, totalDays) 
        let dayStart = start.AddDays(i).ToUnixTimestamp() 
        let nextDay = start.AddDays(i).NextDay().ToUnixTimestamp() 
        where (item.dateline < nextDay 
         && (!item.status.Equals("done") || t.lastactivity >= dayStart) 
        select new { day = nextDay - 1 } 
       ).ToList(); 

var results = itemsPerDay.DistinctBy(t => t.day).Select(
    t => new OpenedItemsPerDay 
    { 
     day = t.day, 
     count = itemsPerDay.Count(v => v.day == t.day) 
    }).AsQueryable(); 

上面的代码执行得太慢,我不确定这是否是一种正确的方法来执行我所做的事情奔向。

我也尝试过使用分组,但被困住了:如果项目被创建得更早,然后DAY_X并且它的状态更改为例如2天后我只能将它与一个组(天)联系起来,我不能数两次或更多。

+0

您是否尝试过运行想组使用原始SQL查询 –

+0

@AlexKrupka是的,我有。我写了一些简单的查询生成器,它生成我这样的SQL查询:'SELECT * FROM items WHERE dateline <= DAY_END AND(status!='done'OR lastactivity> = DAY + 1_START)or dateline <= DAY + 1_END AND状态!='完成'或最后活动> = DAY + 1_START)',并重复30次。然后我手动计数项目。我认为可能有更好的方法来做到这一点。 –

+0

由于这需要顺序处理(一种总运行),所以从数据库获取原始数据并在经典的“foreach”中将其处理到内存中会更容易,更快速。目前你有一个本地序列的交叉连接。 EF在将本地序列转换为SQL时效率不高,查询优化器将很难找到一个好的计划。 –

回答

0

为什么不使用groupby? (不盈的VS所以原谅语法)

var d1 = datetime.now.adddays(-5).ToUnixTimestamp() 
var d2= DateTime.Now.ToUnixTimestamp(); 

var grouppeditems = (for item in items 
where item.lastactivity <= d2 && item.dateline >= d1 && (!item.status.Equals("done") 
select item).GroupBy(gb=>gb.lastactivity) 

foreach (var item in grouppeditems) 
Console.WriteLine (item.Title + " " + item.Count); 

//可能通过这样的分组当天 (D2-gb.lastactivity)/ 86400

+0

lastactivity字段是时间戳,它将按相同的时间戳分组,我需要按天分组。 –

+0

可能想组这样的事情来分组当天(d2-gb.lastactivity)/ 86400 – cechode