1

次の形式のデータを持つ「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 .......
    .......................
    .............................

Entity Frameworkを使用して、たとえば2013年3月のビデオの合計時間をキャプチャし、キャプチャされたビデオの合計時間が週単位になるようにします。次の例:

    Mar 1, 2013     Mar 8, 2013      Mar 15, 2013     Mar 22, 2013
   ================================================================
   500              300              350              200

私は多くのグーグルをしましたが、それを正確に行う方法を見つけることができませんでした。ご案内ください。ご協力いただきありがとうございます。

4

2 に答える 2

6

Ilyaの優れた仕事を却下するのは嫌いです(申し訳ありませんが、少なくとも私はあなたに賛成です)が、これはエンティティフレームワークであるため、SqlFunctionsを使用してデータベースに1つのクエリで仕事をさせることができます。

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#を使用してデータを変換します。

于 2013-03-25T19:41:08.200 に答える
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
于 2013-03-25T15:35:28.210 に答える