C# 如何将列表转换为数据表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15128140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:09:01  来源:igfitidea点击:

How to convert a List into DataTable

c#listado.netdatatabledatarow

提问by Ganeshja

I'm getting values from another data table as input to list. Now i need to save those list values into another DataTable.

我从另一个数据表中获取值作为列表的输入。现在我需要将这些列表值保存到另一个 DataTable 中。

List:

列表:

List<DataRow> list = slectedFieldsTable.AsEnumerable().ToList();
foreach (DataRow dr in slectedFieldsTable.Rows)
{
    list.Add(dr);
}

New Data table :

新数据表:

DataRow newRow = tempTable.NewRow();
newRow["Field Name"] = fieldLabel;
newRow["Field Type"] = fieldType;

for(int gg =0 ; gg<list.Count; gg++)
{
    tempTable.Rows.Add(????);
}

I'm stuck here in adding up rows in to new data table.

我被困在这里将行添加到新数据表中。

回答by Ravi Gadag

use CopyToDataTable() method. CopyToDataTable

使用 CopyToDataTable() 方法。 复制到数据表

IEnumerable<DataRow> query = TempselectedFieldsTable.AsEnumerable().ToList();

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

回答by CodeGuru

Try this:

尝试这个:

     foreach (DataRow dr in list)
     {
        tempTable.Rows.Add(dr);
     }

回答by Jay Doshi

public static DataTable ToDataTable<T>(List<T> items)
{
        DataTable dataTable = new DataTable(typeof(T).Name);

        //Get all the properties
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo prop in Props)
        {
            //Setting column names as Property names
            dataTable.Columns.Add(prop.Name);
        }
        foreach (T item in items)
        {
           var values = new object[Props.Length];
           for (int i = 0; i < Props.Length; i++)
           {
                //inserting property values to datatable rows
                values[i] = Props[i].GetValue(item, null);
           }
           dataTable.Rows.Add(values);
      }
      //put a breakpoint here and check datatable
      return dataTable;
}

回答by Sumon Banerjee

Variable declare:

变量声明:

    DataTable tempTable = new DataTable();
    DataTable slectedFieldsTable = new DataTable();
    DataRow newRow;
    List<object> list = new List<object>();

Add Column in DataTable:

在数据表中添加列:

    slectedFieldsTable = new DataTable();
    slectedFieldsTable.Columns.Add("Field Name");
    slectedFieldsTable.Columns.Add("Field Type");

Add Value in DataTable:

在数据表中添加值:

    slectedFieldsTable.Rows.Add("1", "AAA");
    slectedFieldsTable.Rows.Add("2", "BBB");
    slectedFieldsTable.Rows.Add("3", "CCC");

Convert DataTable to List:

将数据表转换为列表:

  foreach (DataRow dr in slectedFieldsTable.Rows)
    {
        list.Add(dr);
    }

Add Column in another DataTable:

在另一个数据表中添加列:

    tempTable.Columns.Add("Field Name", typeof(string));
    tempTable.Columns.Add("Field Type", typeof(string));

Convert List to dataTable:

将列表转换为数据表:

   foreach(DataRow dr in list)
    {
        newRow = tempTable.NewRow();
        newRow["Field Name"] = dr.ItemArray[0].ToString();
        newRow["Field Type"] = dr.ItemArray[1].ToString();
        tempTable.Rows.Add(newRow);
        tempTable.AcceptChanges();
    }

回答by ??ssa P?ngj?rdenlarp

The answer providing the ToDataTableis a very nice start but it is missing some key elements. Namely, it ignores that Listitem properties may:

提供 的答案ToDataTable是一个非常好的开始,但它缺少一些关键要素。也就是说,它忽略了List项目属性可能:

  • ...be marked ReadOnly
  • ...use the DisplayNameattribute
  • ...have a DefaultValuewhich the DataColumnshould know about
  • ...be Nullable
  • ...be marked BrowsableAttribute(false)
  • ...被标记 ReadOnly
  • ...使用DisplayName属性
  • ...有DefaultValueDataColumn应该知道
  • ...是 Nullable
  • ...被标记 BrowsableAttribute(false)

The following is an extension method to return a DataTableand either accounts for the above or provides the means for your code to apply them. It also uses an Interfaceto get the values from the class object rather than Reflection.

以下是返回 a 的扩展方法,DataTable并且可以说明上述内容或为您的代码提供应用它们的方法。它还使用 anInterface来从类对象而不是 中获取值Reflection

public static DataTable ToDataTable<T>(this IList<T> lst, bool includeAll = true)
{
    DataTable dt = new DataTable();
    DataColumn dc;
    PropertyDescriptor pd;
    bool Browsable;

    PropertyDescriptorCollection propCol = TypeDescriptor.GetProperties(typeof(T));

    for (int n = 0; n < propCol.Count; n++)
    {
        pd = propCol[n];
        Type propT = pd.PropertyType;

        dc = new DataColumn(pd.Name);

        // if Nullable, get underlying type
        // the first test may not be needed
        if (propT.IsGenericType && Nullable.GetUnderlyingType(propT) != null )
        {
            propT = Nullable.GetUnderlyingType(propT);
            dc.DataType = propT;
            dc.AllowDBNull = true;
        }
        else
        {
            dc.DataType = propT;
            dc.AllowDBNull = false;
        }

        // is it readonly?
        if (pd.Attributes[typeof(ReadOnlyAttribute)] != null)
        {
            dc.ReadOnly = ((ReadOnlyAttribute)pd.
                     Attributes[typeof(ReadOnlyAttribute)]).IsReadOnly;
        }         

        // DefaultValue ...
        if (pd.Attributes[typeof(DefaultValueAttribute)] != null)
        {
            dc.DefaultValue = ((DefaultValueAttribute)pd.
                   Attributes[typeof(DefaultValueAttribute)]).Value;
        }

        // caption / display name
        dc.ExtendedProperties.Add("DisplayName", dc.Caption);
        if (pd.Attributes[typeof(DisplayNameAttribute)] != null)
        {
            // these are usually present but blank
            string theName = ((DisplayNameAttribute)pd.
                   Attributes[typeof(DisplayNameAttribute)]).DisplayName;
            dc.Caption = string.IsNullOrEmpty(theName) ? dc.Caption : theName;
            // DGV doesnt use Caption...save for later
            dc.ExtendedProperties["DisplayName"] = dc.Caption;
        }

        Browsable = true;
        dc.ExtendedProperties.Add("Browsable", Browsable);
        var foo = pd.Attributes[typeof(BrowsableAttribute)];
        if (pd.Attributes[typeof(BrowsableAttribute)] != null) 
        {
            Browsable = ((BrowsableAttribute)pd.Attributes[typeof(BrowsableAttribute)]).Browsable;
            // no such thing as a NonBrowsable DataColumn
            dc.ExtendedProperties["Browsable"] = Browsable;
        }

        // ToDo: add support for custom attributes

        if (includeAll || Browsable)
        {
            dt.Columns.Add(dc);
        }
    }

    // the lst could be empty such as creating a typed table
    if (lst.Count == 0) return dt;

    if (lst[0] is IDataValuesProvider)
    {
        IDataValuesProvider dvp;
        // copy the data - let the class do the work
        foreach (T item in lst)
        {
            dvp = (IDataValuesProvider)item;
            dt.Rows.Add(dvp.GetDataValues(includeAll).ToArray());
        }
    }
    else
    {
        List<object> values;
        foreach (T item in lst)
        {
            values =  new List<object>();
            // only Browsable columns added
            for (int n = 0; n < dt.Columns.Count; n++)
            {
                 values.Add(propCol[dt.Columns[n].ColumnName].GetValue(item));
            }
            dt.Rows.Add(values.ToArray());
        }
    }   

    return dt;
}

The method allows you to specify whether columns for non Browsableproperties should be added to the DataTable. Rather than hiding the columns later, you can omit them entirely if you want.

该方法允许您指定是否Browsable应将非属性的列添加到DataTable. 如果您愿意,您可以完全省略它们,而不是稍后隐藏这些列。

An interface proves the means to get the data values from collection members in order (as an alternative to a reflection loop):

接口证明了按顺序从集合成员获取数据值的方法(作为反射循环的替代方案):

public interface IDataValuesProvider
{
    IEnumerable<object> GetDataValues(bool includeAll);
}

... on the class:
public class StockItem : IDataValuesProvider
{
    public int Id { get; set; }
    public string ItemName {get; set;}
    [Browsable(false), DisplayName("Ignore")]
    public string propA {get; set;}
    [ReadOnly(true)]
    public string Zone { get; set; }
    public string Size {get; set;}
    [DisplayName("Nullable")]
    public int? Foo { get; set; }
    public int OnHand {get; set;}
    public string ProdCode {get; set;}
    [Browsable(false)]
    public string propB { get; set; }
    public DateTime ItemDate {get; set;}

    // IDataValuesProvider implementation
    public IEnumerable<object> GetDataValues(bool IncludeAll)
    {
        List<object> values = new List<object>();

        values.AddRange(new object[] {Id, ItemName });
        if (IncludeAll) values.Add(propA);

        values.AddRange(new object[] { Zone, Size, Foo, OnHand, ProdCode });
        if (IncludeAll) values.Add(propB);

        values.Add(ItemDate);

        return values;
    }
}

Add the data values in the same order as they are listed in your class; be sure to update it when you add properties. The reflection version is still there so you can do it either way.

按照类中列出的顺序添加数据值;添加属性时一定要更新它。反射版本仍然存在,因此您可以使用任何一种方式。

Finally, there are a few common Attributes which do not have a related DataColumnproperty. The method stores these for you as ExtendedPropertiesallowing you to easily apply them to the DGV:

最后,还有一些Attribute没有相关DataColumn属性的common 。该方法为您存储这些,ExtendedProperties以便您可以轻松地将它们应用到 DGV:

var dtX = someData.ToDataTable();

dgvB.SuspendLayout();
dgvB.DataSource = dtX;

// process extended props
foreach (DataColumn dc in dtX.Columns)
{
    // no need to test, the code adds them everytime
    //if (dc.ExtendedProperties.ContainsKey("DisplayName"))
    //{ 
        dgvB.Columns[dc.ColumnName].HeaderText = dc.ExtendedProperties["DisplayName"].ToString(); 
    //}
    //if (dc.ExtendedProperties.ContainsKey("Browsable"))
    //{
        dgvB.Columns[dc.ColumnName].Visible = (bool)dc.ExtendedProperties["Browsable"];
    //}
}
dgvB.ResumeLayout();

Results using a list of the class shown above:

使用上面显示的类列表的结果:

enter image description here

在此处输入图片说明

Both OnHandand Fooshow the DisplayNameand both PropAand PropBare hidden. Most importantly, columns created for ReadOnlyand Nullableproperties act accordingly.

双方OnHandFoo显示DisplayName两者PropAPropB被隐藏。最重要的是,为ReadOnlyNullable属性创建的列会相应地起作用。