我有一个名为“VideoData”的后端表,其中包含以下格式的数据:
VideoID RecordingStarted RecordingEnded
==============================================================
abc123 2013-03-01 15:30:00 2013-03-01 15:40:00
def123 2013-03-06 12:00:00 2013-03-06 12:40:00
ijk123 2013-03-10 11:00:00 2013-03-10 11:05:00
klm123 2013-03-12 10:05:00 2013-03-12 10:25:00
And list goes on .......
.......................
.............................
使用实体框架我希望获得2013年3月捕获的视频总时数,以便捕获视频的总小时数为Weekwise。 以下列方式举例:
Mar 1, 2013 Mar 8, 2013 Mar 15, 2013 Mar 22, 2013
================================================================
500 300 350 200
我用Google搜索了很多内容,但无法弄清楚如何正确地做到这一点。请指导。 谢谢你的帮助。
答案 0 :(得分:6)
我讨厌推翻Ilya出色的工作(对不起伙伴,至少我赞成你),但由于这是实体框架,因此可以让数据库通过SqlFunctions只用一个查询来完成工作:< / p>
context.Videos.Select(t => new
{
Year = SqlFunctions.DatePart("yyyy", t.RecordingStarted),
Week = SqlFunctions.DatePart("ww", t.RecordingStarted),
Hours = SqlFunctions.DateDiff("hh", t.RecordingStarted, t.RecordingEnded)
})
.GroupBy(x => new { x.Year, x.Week} )
.Select (x => new { x.Key.Year, x.Key.Week, TotalHours = x.Sum(p => p.Hours)} )
输出类似于
2013 9 500
2013 10 300
...
在Sql Server中,从年份+周到日期非常困难。如果这确实是一个要求,您可以考虑建立一个参考表,其中包含年份+周数和第一天的日期。或者获取内存中的数据(.ToList()
)并使用C#转换数据。
答案 1 :(得分:2)
好吧,这项任务似乎非常有趣。我已经使用本地数据实现了基本功能。免费评论更多功能。你有点麻烦
//local data for testing
var data = new[] {
new {VideoId = "abc123",RecordindStarted = DateTime.Parse("2013-03-01 15:30:00"),RecordingEnded = DateTime.Parse("2013-03-01 15:40:00")},
new {VideoId = "def123",RecordindStarted = DateTime.Parse("2013-03-06 12:00:00"),RecordingEnded = DateTime.Parse("2013-03-06 12:40:00")},
new {VideoId = "de1223",RecordindStarted = DateTime.Parse("2013-03-06 12:30:00"),RecordingEnded = DateTime.Parse("2013-03-06 12:50:00")},
new {VideoId = "ijk123",RecordindStarted = DateTime.Parse("2013-03-10 11:00:00"),RecordingEnded = DateTime.Parse("2013-03-10 11:05:00")},
new {VideoId = "klm123",RecordindStarted = DateTime.Parse("2013-03-12 10:05:00"),RecordingEnded = DateTime.Parse("2013-03-12 10:25:00")},
new {VideoId = "klm123",RecordindStarted = DateTime.Parse("2013-03-12 10:05:00"),RecordingEnded = DateTime.Parse("2013-03-13 10:25:00")},
};
var calendar = new GregorianCalendar();
var ungroupedTotalHours = data.Select(d => GetHoursPerDays(d.RecordindStarted, d.RecordingEnded));
var groupedTotalHours =
ungroupedTotalHours.SelectMany(v => v)
.GroupBy(v=> v.Key)
.ToDictionary(v => v.Key, v => v.Sum(val => val.Value));
var result =
groupedTotalHours.GroupBy(v =>calendar.GetWeekOfYear( v.Key, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
.ToDictionary(v => "Week "+ v.Key, row => row.Sum(val => val.Value));
Console.WriteLine ( string.Join(Environment.NewLine, result.Select(r => r.Key +" has "+r.Value+" hours")) );
核心逻辑转向此方法:
public IDictionary<DateTime, int> GetHoursPerDays(DateTime start, DateTime end)
{
if(end.Date == start.Date)
return new Dictionary<DateTime, int>{{start.Date, (end - start).Minutes}};
return Enumerable.Range(1, (int)(end - start).TotalHours)
.Select(v => start.AddHours(v))
.GroupBy(v => v.Date)
.ToDictionary( v => v.Key, r => r.Count());
}
打印:
Week 9 has 10 hours
Week 10 has 65 hours
Week 11 has 44 hours