2013-04-16 75 views
0

我有一個DataTable已經下面的列集團通過時間(僅限小時部分)在LINQ

CallTime CallType 

15:45:00 Voice 
15:30:54 Voice 
00:12:14 SMS 
01:13:47 Voice 
05:48:23 SMS 
12:00:47 Voice 

現在我想使用LINQ結果像這樣

Hrs Count 
00 1 
01 1 
05 1 
12 1 
15 2 

我已經嘗試使用組Linq,但是沒有把握好。

我用下面的代碼

var groupQuery = from table in Foundrows.AsEnumerable() 
         group table by table["Call Time"] into groupedTable 
         select new 
         { 
          CallTime = groupedTable.Key, 
          CallCount = groupedTable.Count() 
         }; 
+0

是什麼類型'CallTime'是時間跨度?或字符串 – Habib

+0

CallTime是DateTime字段嗎?如果是這樣,你想按小時或按日期+小時分組嗎? –

+0

它是字符串,但可以作爲時間成功地解析 –

回答

3
var groupQuery = from r in Foundrows.AsEnumerable() 
       group r by r.Field<TimeSpan>("CallTime").Hours into g 
       select new { 
        Hrs = g.Key, 
        CallCount = g.Count() 
       }; 

如果您string類型的列然後就分析它的價值爲TimeSpan

var groupQuery = from r in Foundrows.AsEnumerable() 
       let time = TimeSpan.Parse(r.Field<string>("CallTime")) 
       group r by time.Hours into g 
       select new { 
        Hrs = g.Key, 
        CallCount = g.Count() 
       }; 

Foundrows.AsEnumerable() 
     .Select(r => { 
      TimeSpan time; 
      return new { 
       Row = r, 
       Time = TimeSpan.TryParse(r.Field<string>("CallTime"), out time) ? 
         time : (TimeSpan?)null 
      }; 
     }) 
     .Where(x => x.Time.HasValue) 
     .GroupBy(x => x.Time.Value.Hours) 
     .Select(g => new { 
      Hrs = g.Key, 
      CallCount = g.Count() 
     }); 

或者你可以使用TryParse這將返回null的TimeSpan方法是這樣的:

public static TimeSpan? TryParse(string s) 
{ 
    TimeSpan time; 
    if (TimeSpan.TryParse(s, out time)) 
     return time; 

    return null; 
} 

而且在原來的查詢使用它:

var groupQuery = from r in Foundrows.AsEnumerable() 
       let time = TryParse(r.Field<string>("CallTime")) 
       where time.HasValue 
       group r by time.Value.Hours into g 
       select new { 
        Hrs = g.Key, 
        CallCount = g.Count() 
       }; 
+0

如果我想使用TryParse代替解析,我需要在代碼中做什麼更改 –

+0

還需要在同一個linq查詢中按hrs排序結果順序 –

+0

@RajeevKumar如果你有有效的時間值,那麼所有的都應該按原樣工作。但如果你不這樣做,那麼堅持一下,我會在一分鐘內添加'TryParase' –

2

如果按小時和外地要組「通話時間」是一個DateTime領域:

var groupQuery = from row in Foundrows.AsEnumerable() 
       let hour = row.Field<DateTime>("Call Time").Hour 
       group row by hour into hourGroup 
       select new { 
        CallHour = hourGroup.Key, 
        CallCount = hourGroup.Count() 
       }; 

如果你想按的Date + Hour組合:

var groupQuery = from row in Foundrows.AsEnumerable() 
       let date = row.Field<DateTime>("Call Time") 
       let hour = date.Hour 
       group row by new{ date, hour } into dateHourGroup 
       select new { 
        CallDate = dateHourGroup.Key.date, 
        CallHour = dateHourGroup.Key.hour, 
        CallCount = dateHourGroup.Count() 
       }; 

編輯:如果它實際上是一個TimeSpan(因爲它似乎是),使用lazyberezovsky的做法:)

comment:如果我想用TryParse代替Parse,什麼 變化會我需要在代碼中做出?

我建議創建一個擴展,它允許返回一個Nullable<TimeSpan>,那麼你就可以檢查是否HasValue==true

public static TimeSpan? TryGetTimeSpan(this string tsString, string format = null) 
{ 
    TimeSpan ts; 
    bool success; 
    if (format == null) 
     success = TimeSpan.TryParse(tsString, out ts); 
    else 
     success = TimeSpan.TryParseExact(tsString, format, null, TimeSpanStyles.None, out ts); 
    return success ? (TimeSpan?)ts : (TimeSpan?)null; 
} 

現在這個查詢的工作效率和不使用無證側efects(如您在查詢中使用的TimeSpan.TryParse本地TimeSpan變量):

var groupQuery = from r in Foundrows.AsEnumerable() 
       let time = r.Field<string>("CallTime").TryGetTimeSpan() 
       where time.HasValue 
       group r by time.Value.Hours into g 
       select new 
       { 
        Hrs = g.Key, 
        CallCount = g.Count() 
       }; 
+0

感謝蒂姆..你真的很容易 –

+0

+1更新。當我測試我的時候,你做得更快了:) –