2014-11-14 51 views
3

我有以下查詢需要DataTable並計算值出現在countField列中的次數。LINQ查詢在計算int時失敗

var countField = "class" 
var query = from row in myDataTable.AsEnumerable() 
      group row by row.Field<string>(countField) 
      into sumry 
      orderby sumry.Count() descending 
      select new 
      { 
       Text = sumry.Key, 
       CountofRows = sumry.Count() 
      }; 

按預期工作,除非該列包含十進制值。我並不熟悉linq知道要更改什麼以允許它計算十進制值的實例。

我該如何使這個語句更健壯,因此它可以用於指定列中包含的任何數據類型?

回答

3

你可以只取出使用DataRow's索引值,並將其轉換爲string

var query = from row in myDataTable.AsEnumerable() 
     group row by row[countField].ToString() 
     into sumry 
     orderby sumry.Count() descending 
     select new 
     { 
      Text = sumry.Key, 
      CountofRows = sumry.Count() 
     }; 

這應該按預期工作所有類型。

+0

我覺得這很容易。我試圖將它轉換爲一個字符串,但不是與索引器。這工作完美。謝謝! – davids 2014-11-14 18:35:31

1

您可以獲取該列的類型並使用反射來調用Field<T>()。 (請參閱調用一般方法的答案:https://stackoverflow.com/a/232621/409259

var columnType = myDataTable.Columns[countField].DataType; 
var method = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(string) }); 
var generic = method.MakeGenericMethod(columnType); 

var query = from row in myDataTable.AsEnumerable() 
      group row by generic.Invoke(null, new object[] { row, countField }) 
      into sumry 
      orderby sumry.Count() descending 
      select new 
      { 
       Text = sumry.Key, 
       CountOfRows = sumry.Count() 
      }; 
+0

這是否比Selman22的答案提供了一個優勢?這看起來更復雜,並不總是很糟糕,但我看不出額外的代碼提供了什麼? – davids 2014-11-14 23:11:27

+1

只有當'ToString()'會丟失可區分不同值的信息時才重要。例如,'DateTime.ToString()'將時間格式化爲秒。如果你需要在毫秒時間內分組,那麼它就不適合你。我認爲所有其他原始類型,'DateTime'到第二個,'ToString'都可以。對於複雜類型,您必須牢記這一點,以確保分組按照需要進行。 – 2014-11-15 01:51:46