简体   繁体   English

如何转换IEnumerable <T> 列出到C#中的数据表

[英]How to convert IEnumerable<T> list to Datatable in C#

I am stuck with the following problem: 我陷入以下问题:

I normally use the function below to transfer custom data to DataTable but in this case the input data is a class composed of lists. 我通常使用下面的函数将自定义数据传输到DataTable,但在这种情况下,输入数据是由列表组成的类。 I just need to write in DataTable the first element of each list per row. 我只需要在DataTable中写出每行每个列表的第一个元素。 Could you help me to adjust this function in order to achieve this? 您能帮我调整此功能以实现此功能吗?

public List<int> xID { get; set; }
public List<string> xName { get; set; }
public List<string> xType { get; set; }
public List<string> xSource { get; set; }
public List<int> xmdID { get; set; }
public List<string> xMDName { get; set; }
public List<string> xUser { get; set; }

public static DataTable ListToDataTable<T>(IEnumerable<T> list)
{
    Type type = typeof(T);
    var properties = type.GetProperties();

    DataTable dataTable = new DataTable();
    foreach (PropertyInfo info in properties)
    {
        dataTable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
    }

    foreach (T entity in list)
    {
        object[] values = new object[properties.Length];
        for (int i = 0; i < properties.Length; i++)
        {
            values[i] = properties[i].GetValue(entity);
        }

        dataTable.Rows.Add(values);
    }

    return dataTable;
}

Based in Carra answer I tried the code below but it did not recognize pType type (The type or namespace name 'pType' could not be found (are you missing a using directive or an assembly reference?)) 基于Carra的答案,我尝试了以下代码,但未识别pType类型(找不到类型或名称空间名称'pType'(您是否缺少using指令或程序集引用?)

var v = properties[i].GetValue(entity);
Type pType = properties[i].PropertyType;

if (pType.IsGenericType && pType.GetGenericTypeDefinition() == typeof(Nullable<>))
pType = Nullable.GetUnderlyingType(pType);

                if (pType.IsEnum)
                    pType = Enum.GetUnderlyingType(pType);

                if (v.GetType().GetGenericTypeDefinition() == typeof(List<>))
                {
                    values[i] = (v as List<pType>).First();
                }

UPDATE 更新

I guess it is not the best solution because it does not accept any List type but it is the best I could do: 我猜这不是最好的解决方案,因为它不接受任何List类型,但是这是我能做到的最好的方法:

    public static DataTable ListToDataTable<T>(IEnumerable<T> list)
    {
        Type type = typeof(T);
        var properties = type.GetProperties();

        DataTable dataTable = new DataTable();
        foreach (PropertyInfo info in properties)
        {
            Type propertyType = info.PropertyType;

            if (propertyType.IsGenericType | propertyType.GetGenericTypeDefinition() == typeof(Nullable<>) | propertyType.IsEnum)
                propertyType = propertyType.GetGenericArguments()[0];

            dataTable.Columns.Add(new DataColumn(info.Name, propertyType));
        }

        foreach (T entity in list)
        {
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
                var v = properties[i].GetValue(entity);
                Type pType = v.GetType().GetGenericArguments().FirstOrDefault();

                if (v.GetType().GetGenericTypeDefinition() == typeof(List<>))
                {
                    if(pType == typeof(int))
                        values[i] = (v as List<int>).First();
                    else if(pType == typeof(string))
                        values[i] = (v as List<string>).First();
                }
                else
                {
                    values[i] = v;
                }
            }
            dataTable.Rows.Add(values);
        }
        return dataTable;
    }

You need something like this: 您需要这样的东西:

foreach (PropertyInfo info in properties)
{
    if(info.PropertyType == typeof(IEnumerable))
    {
       dataTable.Columns.Add(new DataColumn(info.Name, info.Cast<object>().First().GetType());
    }
    else
    {
       dataTable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
    }
}

foreach (T entity in list)
{
    object[] values = new object[properties.Length];
    for (int i = 0; i < properties.Length; i++)
    {
        var v = properties[i].GetValue(entity);
        if(v is IEnumerable)
        {
          values[i] = (v.Cast<object>().First()).First();
        }
        else
        {
          values[i] = v;
        }
    }

    dataTable.Rows.Add(values);
}

This works for me. 这对我有用。 I got it here and modified it a little bit. 我在这里找到它并对其进行了一些修改。

public static DataTable ToDataTable<T>(this System.Collections.Generic.List<T> collection, string _sTableName) {
        var table = new DataTable(_sTableName);
        var type = typeof(T);
        var properties = type.GetProperties();

        //Create the columns in the DataTable
        foreach (var property in properties) {
            if (property.PropertyType == typeof(int?)) {
                table.Columns.Add(property.Name, typeof(int));
            } else if (property.PropertyType == typeof(decimal?)) {
                table.Columns.Add(property.Name, typeof(decimal));
            } else if (property.PropertyType == typeof(double?)) {
                table.Columns.Add(property.Name, typeof(double));
            } else if (property.PropertyType == typeof(DateTime?)) {
                table.Columns.Add(property.Name, typeof(DateTime));
            } else if (property.PropertyType == typeof(Guid?)) {
                table.Columns.Add(property.Name, typeof(Guid));
            } else if (property.PropertyType == typeof(bool?)) {
                table.Columns.Add(property.Name, typeof(bool));
            } else {
                table.Columns.Add(property.Name, property.PropertyType);
            }
        }

        //Populate the table
        foreach (var item in collection) {
            var row = table.NewRow();
            row.BeginEdit();
            foreach (var property in properties) {
                row[property.Name] = property.GetValue(item, null) ?? DBNull.Value;
            }

            row.EndEdit();
            table.Rows.Add(row);
        }

        return table;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM