将动态列表转换为DataTable C#

11

我正在努力寻找并思考如何将动态列表转换为数据表,使用c#语言,请给予建议,谢谢。

List<dynamic>dlist=new List<dynamic>
DataTable 

你的意思是说,items中的每个属性/字段都应该成为datatable中的一列?如果dlist中的每个项都是不同类型的,那怎么办?最重要的是:你已经尝试过什么了吗?展示一下你的努力。 - MarcinJuraszek
9个回答

12

我认为你在寻找类似于这样的东西。希望它对你有用。

从动态列表到DataTable:

   List<dynamic> dlist=new List<dynamic> 
   var json = JsonConvert.SerializeObject(dlist);
   DataTable dataTable = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));

还可以从DataTable获取JsonString:

string JSONresult = JsonConvert.SerializeObject(dataTable);

2
超棒的解决方案 - Reyan Chougle
1
很棒的解决方案@Majedur兄弟 :) - jishan siddique
1
这个问题应该标记为已回答。 - MaliEbbae

5
以下是将任何列表对象转换为数据表的方法:
 public DataTable ConvertToDataTable<T>(IList<T> data)
    {
        PropertyDescriptorCollection properties =
           TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;

    }

http://social.msdn.microsoft.com/Forums/vstudio/en-US/6ffcb247-77fb-40b4-bcba-08ba377ab9db/converting-a-list-to-datatable?forum=csharpgeneral


3
 public DataTable ToDataTable<T>(dynamic items)
    {

        DataTable dtDataTable = new DataTable();
        if (items.Count == 0) return dtDataTable;

        ((IEnumerable)items[0]).Cast<dynamic>().Select(p => p.Name).ToList().ForEach(col => { dtDataTable.Columns.Add(col); });

        ((IEnumerable)items).Cast<dynamic>().ToList().
            ForEach(data =>
            {
                DataRow dr = dtDataTable.NewRow();
                ((IEnumerable)data).Cast<dynamic>().ToList().ForEach(Col => { dr[Col.Name] = Col.Value; });
                dtDataTable.Rows.Add(dr);
            });
        return dtDataTable;
    }

1
这对我有用,但是由于我的可枚举包含KeyValuePairs,所以我不得不将“Name”交换为“Key”。 - Joe Zack
如果IEnumerable<T>不包含任何项,我认为这种方法行不通 - 它将返回一个没有列或行的DataTable。我希望得到一个有列但没有行的DataTable。 - Colin

2
我不知道你为什么需要这个,但是你可以使用反射来使用 ObjectShredder,它可以将任何东西转换为 DataTable,即使是动态或匿名类型:

实现 CopyToDataTable<T>,其中泛型类型 T 不是 DataRow

然而,我的建议是不要将扩展方法命名为 CopyToDataTable,而是例如 CopyAnyToDataTable,以避免与现有的扩展方法CopyToDataTable冲突。


0

公共静态数据表 DynamicToDT(List objects)

    {
        var data = objects.ToArray();
        if (data.Count() == 0) return null;
        var dt = new DataTable();
        foreach (var key in ((IDictionary<string, object>)data[0]).Keys)
        {
            dt.Columns.Add(key);
        }
        foreach (var d in data)
        {
            dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
        }
        return dt;
    }

0
使用这个函数,
public static DataTable ConvertToDatatable<T>(this IList<T> data)
{
    PropertyDescriptorCollection props =
        TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for(int i = 0 ; i < props.Count ; i++)
    {
        PropertyDescriptor prop = props[i];
        table.Columns.Add(prop.Name, prop.PropertyType);
    }
    object[] values = new object[props.Count];
    foreach (T item in data)
    {
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = props[i].GetValue(item);
        }
        table.Rows.Add(values);
    }
    return table;        
    }

0

使用C#将动态列表对象转换为DataTable

 public DataTable DynamicToDT(List<object> objects)
        {
            DataTable dt = new DataTable("StudyRecords"); // Runtime Datatable          
            string[] arr = { "Name", "Department", "CollegeName", "Address" };// Column Name for DataTable
            if (objects != null && objects.Count > 0)
            {
                for (int i = 0; i < objects.Count; i++)
                {
                    dt.Columns.Add(arr[i]);
                    if (i == 0)
                    {
                        var items = objects[0] as IEnumerable<string>;
                        foreach (var itm in items)
                        {
                            DataRow dr1 = dt.NewRow(); // Adding values to Datatable  
                            dr1[arr[i]] = itm;
                            dt.Rows.Add(dr1);
                        }
                    }
                    else
                    {
                        var items = objects[i] as IEnumerable<string>;
                        int count = 0;
                        foreach (var itm in items)
                        {
                            dt.Rows[count][arr[i]] = itm;
                            count++;
                        }
                    }
                }

                return dt; // Converted Dynamic list to Datatable  
            }
            return null;
        }

0
如果底层类型是ExpandoObject,则需要检查IDictionary而不是通过反射进行。希望这能帮助未来的某个人:
    public static DataTable ConvertToDataTable<T>(IEnumerable<T> data)
    {
        DataTable table = new DataTable();
        foreach (T item in data)
        {
            if (item is IDictionary<string, object> dict)
            {
                foreach (var key in dict)
                {
                    table.Columns.Add(key.Key, key.Value?.GetType() ?? typeof(object));
                }
                break;
            }
            foreach (var prop in typeof(T).GetProperties())
            {
                table.Columns.Add(prop.Name, prop.PropertyType);
            }
            break;
        }

        DataRow row = null;
        foreach (T item in data)
        {
            if (item is IDictionary<string, object> dict)
            {
                row = table.NewRow();
                foreach (var key in dict)
                {
                    row[key.Key] = key.Value;
                }
                table.Rows.Add(row);
                continue;
            }

            row = table.NewRow();
            foreach (var prop in typeof(T).GetProperties())
            {
                row[prop.Name] = prop.GetValue(item);
            }
            table.Rows.Add(row);
        }
        return table;
    }

如果IEnumerable<T>不包含任何项,我认为这不会起作用 - 它将返回一个没有列或行的DataTable。我想要一个有列但没有行的DataTable。 - Colin
@Colin 如果你在底层使用了Dynamic/ExpandoObject,除非该列表中至少有一项,否则你不需要指定任何列,因为否则类型T实际上是不存在的,因为它甚至都没有被定义。 - Daniel Lorenz

0
// Obtem a lista dinamica via chamada API
List<dynamic> resultado = ExecutaQuery(sql);

// converte a lista dinamica com o resultado em JSON
string json = JsonConvert.SerializeObject(resultado);

// converte o json em datatable
DataTable dataTable = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));

请确保用英语解释您的代码,因为您当前正在使用 Stack Overflow 的英语版本。 - Jeremy Caney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接