将Dictionary列表转换为DataTable

时间:2013-03-08 12:06:33

标签: c# .net casting datatable

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

private DataTable ChangeToDictionary(List<Dictionary<string,int>> list)
       {
           DataTable datatTableReturn = new DataTable();

           if (list.Count() > 0)
           {
               Dictionary<string, int> 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;

       }

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

8 个答案:

答案 0 :(得分:11)

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

static DataTable ToDataTable(List<Dictionary<string, int>> 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<string,int> 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<Dictionary<string, int>> it = new List<Dictionary<string, int>>();
    Dictionary<string, int> dict = new Dictionary<string, int>();
    dict.Add("a", 1);
    dict.Add("b", 2);
    dict.Add("c", 3);
    it.Add(dict);
    dict = new Dictionary<string, int>();
    dict.Add("bob", 34);
    dict.Add("tom", 37);
    it.Add(dict);
    dict = new Dictionary<string, int>();
    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();

}

输出看起来像......

a       b       c       bob     tom     Yip Yip Yap Yap
1       2       3
                        34      37
                                        8       9

答案 1 :(得分:5)

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

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

以下是“优雅”解决方案的一个示例,但随之而来的是它不具有可读性。

private static DataTable ToDictionary(List<Dictionary<string, int>> 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<object>().ToArray()));

    return result;
}

答案 2 :(得分:1)

下面的代码怎么样?

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

private static DataTable DictionariesToDataTable<T>(
        IEnumerable<IDictionary<string, T>> 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;
    }
} 

答案 3 :(得分:1)

试试这个:

    private DataTable GetDataTableFromDictionaries<T>(List<Dictionary<string, T>> 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;
    }

答案 4 :(得分:0)

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

private DataTable DictonarysToDataTable(List<Dictionary<string, int>> list) 
    {
        DataTable table = new DataTable();

        foreach (Dictionary<string,string> dict in list)        //for every dictonary in the list ..
        {
            foreach (KeyValuePair<string,int> 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,这只适用于一个字典..我没有想到它。 但是,你可以修改它以适用于Dictionarys列表..

答案 5 :(得分:0)

请试一试

        DataTable table = new DataTable();

        foreach (IDictionary<string, object> row in DeviceTypeReport)
        {
            foreach (KeyValuePair<string, object> entry in row)
            {
                if (!table.Columns.Contains(entry.Key.ToString()))
                {
                    table.Columns.Add(entry.Key);
                }
            }
            table.Rows.Add(row.Values.ToArray());
        }

答案 6 :(得分:0)

private DataTable toDataTable(List<RetirementDiskModelDto> retirementDiskModelDtos)
        {
            DataTable result = new DataTable();
            foreach (var col in retirementDiskModelDtos.FirstOrDefault().Items)
                result.Columns.Add(col.Key);

            foreach (var row in retirementDiskModelDtos)
            {
                DataRow newrow = result.NewRow();
                foreach (var col in retirementDiskModelDtos.FirstOrDefault().Items)
                    newrow[col.Key] = col.Value;
                result.Rows.Add(newrow);
            }
            return result;
        }

答案 7 :(得分:0)

尝试一下

List<Dictionary<string, object>> ListDic;

var stringListDic = JsonConvert.SerializeObject(ListDic);

var dataTable = JsonConvert.DeserializeObject<DataTable>(stringListDic);