如何使用List<T>填充datatable

35

如何将列表转换为数据表

[Serializable]
public class Item
{
    public string Name { get; set; }
    public double Price { get; set; }
    public string @URL { get; set; }

    public Item(string Name, string Price, string @URL)
    {
        this.Name = Name;
        this.Price = Convert.ToDouble(Price);
        this.@URL = @URL;
    }

    public override string ToString()
    {
        return this.Name;
    }
}

我尝试使用:

static DataTable ConvertToDatatable(List<Item> list)
{
    DataTable dt = new DataTable();

    dt.Columns.Add("Name");
    dt.Columns.Add("Price");
    dt.Columns.Add("URL");
    foreach (var item in list)
    {
        dt.Rows.Add(item.Name, Convert.ToString(item.Price), item.URL);
    }

    return dt;
}

现在我的页面上出现了一个空白的框,怎么办?帮帮我!我该怎么做才能让这个框显示数据呢?


1
你说 itemDataView 是空的。它具体是什么并且它来自哪里?这看起来似乎是一个与将 List<T> 转换为 DataTable 的问题不同的问题。 - Alex Wiese
itemDataView是由WindowsForm工具箱生成的。 - MikaAK
请明确您的问题。您的标题说您遇到了生成“dataTable”的问题,但似乎这根本不是问题所在。您的问题在于“itemDataView”。 - Hossain Muctadir
我原以为是数据表。 - MikaAK
3个回答

47

如果你的类对象中有可空属性:

private static DataTable ConvertToDatatable<T>(List<T> data)
{
    PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for (int i = 0; i < props.Count; i++)
    {
        PropertyDescriptor prop = props[i];
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            table.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]); 
        else
            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;
 }

35

试试这个

static DataTable ConvertToDatatable(List<Item> list)
{
    DataTable dt = new DataTable();

    dt.Columns.Add("Name");
    dt.Columns.Add("Price");
    dt.Columns.Add("URL");
    foreach (var item in list)
    {
        var row = dt.NewRow();

        row["Name"] = item.Name;
        row["Price"] = Convert.ToString(item.Price);
        row["URL"] = item.URL;

        dt.Rows.Add(row);
    }

    return dt;
}

1
我仍然得到DataGridView为空的错误。 - MikaAK
那么,你的问题不在于转换,而是在于你添加到窗体中的“DataGridView”控件。尝试将其删除并重新添加,将名称更改为有意义的内容。 - Alex Wiese
并且它能够正常工作,谢谢!抱歉,但这是我使用的代码,DataGridView 的删除和重新添加起作用了。 - MikaAK
@alexw 谢谢,对我来说运行良好。 - User5590

2

我不得不想出一个替代方案,因为这里列出的选项都不能在我的情况下使用。我正在使用一个IEnumerable和底层数据是一个IEnumerable,而属性不能被枚举。这个方法解决了问题:

// remove "this" if not on C# 3.0 / .NET 3.5
public static DataTable ConvertToDataTable<T>(this IEnumerable<T> data)
{
    List<IDataRecord> list = data.Cast<IDataRecord>().ToList();

    PropertyDescriptorCollection props = null;
    DataTable table = new DataTable();
    if (list != null && list.Count > 0)
    {
        props = TypeDescriptor.GetProperties(list[0]);
        for (int i = 0; i < props.Count; i++)
        {
            PropertyDescriptor prop = props[i];
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        }
    }
    if (props != null)
    {
        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) ?? DBNull.Value;
            }
            table.Rows.Add(values);
        }
    }
    return table;
}

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