将字典列表转换为DataTable

目前我们通过循环遍历列表和字典的每个值来完成此操作:

private DataTable ChangeToDictionary(List<Dictionary> list) { DataTable datatTableReturn = new DataTable(); if (list.Count() > 0) { Dictionary haeders = list.ElementAt(0); foreach (var colHead in haeders) { datatTableReturn.Columns.Add(colHead.Key); } } foreach (var row in list) { DataRow dataRow = datatTableReturn.NewRow(); foreach (var col in row) { dataRow[col.Key] = col.Value; } datatTableReturn.Rows.Add(dataRow); } return datatTableReturn; } 

但有更好的方法吗? 循环这么多次感觉并不好

上面的答案没有解决字典超过1行的问题。 该解决方案解决了该问题。

 static DataTable ToDataTable(List> list) { DataTable result = new DataTable(); if (list.Count == 0) return result; var columnNames = list.SelectMany(dict=>dict.Keys).Distinct(); result.Columns.AddRange(columnNames.Select(c=>new DataColumn(c)).ToArray()); foreach (Dictionary item in list) { var row = result.NewRow(); foreach (var key in item.Keys) { row[key] = item[key]; } result.Rows.Add(row); } return result; } static void Main(string[] args) { List> it = new List>(); Dictionary dict = new Dictionary(); dict.Add("a", 1); dict.Add("b", 2); dict.Add("c", 3); it.Add(dict); dict = new Dictionary(); dict.Add("bob", 34); dict.Add("tom", 37); it.Add(dict); dict = new Dictionary(); dict.Add("Yip Yip", 8); dict.Add("Yap Yap", 9); it.Add(dict); DataTable table = ToDictionary(it); foreach (DataColumn col in table.Columns) Console.Write("{0}\t", col.ColumnName); Console.WriteLine(); foreach (DataRow row in table.Rows) { foreach (DataColumn column in table.Columns) Console.Write("{0}\t", row[column].ToString()); Console.WriteLine(); } Console.ReadLine(); } 

输出看起来像……

 abc bob tom Yip Yip Yap Yap 1 2 3 34 37 8 9 

速度,优雅和可重用性不会在一起。 你总是选择更重要的一个,并尝试平衡其他两个。

代码越快,它就越丑陋。 它更漂亮,更不可重复使用。

这是一个“优雅”解决方案的例子,但这与它的可读性不同。

 private static DataTable ToDictionary(List> list) { DataTable result = new DataTable(); if (list.Count == 0) return result; result.Columns.AddRange( list.First().Select(r => new DataColumn(r.Key)).ToArray() ); list.ForEach(r => result.Rows.Add(r.Select(c => c.Value).Cast().ToArray())); return result; } 

试试这个:

  private DataTable GetDataTableFromDictionaries(List> list) { DataTable dataTable = new DataTable(); if (list == null || !list.Any()) return dataTable; foreach (var column in list.First().Select(c => new DataColumn(c.Key, typeof(T)))) { dataTable.Columns.Add(column); } foreach (var row in list.Select( r => { var dataRow = dataTable.NewRow(); r.ToList().ForEach(c => dataRow.SetField(c.Key, c.Value)); return dataRow; })) { dataTable.Rows.Add(row); } return dataTable; } 

如下代码怎么样?

很好,因为它只迭代每一行一次。 它应该很快,我已经包含了明显的例外,以使代码更安全。

 private static DataTable DictionariesToDataTable( IEnumerable> source) { if (source == null) { return null; } var result = new DataTable(); using (var e = source.GetEnumerator()) { if (!e.MoveNext()) { return result; } if (e.Current.Keys.Length == 0) { throw new InvalidOperationException(); } var length = e.Current.Keys.Length; result.Columns.AddRange( e.Current.Keys.Select(k => new DataColumn(k, typeof(T))).ToArray()); do { if (e.Current.Values.Length != length) { throw new InvalidOperationException(); } result.Rows.Add(e.Current.Values); } while (e.MoveNext()); return result; } } 

试试我的解决方案,对我来说似乎很干净:

 private DataTable DictonarysToDataTable(List> list) { DataTable table = new DataTable(); foreach (Dictionary dict in list) //for every dictonary in the list .. { foreach (KeyValuePair entry in dict) //for every entry in every dict { if (!myTable.Columns.Contains(entry.Key.ToString()))//if it doesn't exist yet { myTable.Columns.Add(entry.Key); //add all it's keys as columns to the table } } table.Rows.Add(dict.Values.ToArray()); //add the the Values of every dict in the list as a new row } return table; } 

编辑:哦Snap,这只适用于一个词典..我没有想到它。 但是maybie你可以修改它来为Dictionarys列表工作..

请试一试

  DataTable table = new DataTable(); foreach (IDictionary row in DeviceTypeReport) { foreach (KeyValuePair entry in row) { if (!table.Columns.Contains(entry.Key.ToString())) { table.Columns.Add(entry.Key); } } table.Rows.Add(row.Values.ToArray()); }