我从另一个数据表中获取值作为列表的输入。现在我需要将这些列表值保存到另一个DataTable中。
列表:
List<DataRow> list = slectedFieldsTable.AsEnumerable().ToList();
foreach (DataRow dr in slectedFieldsTable.Rows)
{
list.Add(dr);
}
新数据表:
DataRow newRow = tempTable.NewRow();
newRow["Field Name"] = fieldLabel;
newRow["Field Type"] = fieldType;
for(int gg =0 ; gg<list.Count; gg++)
{
tempTable.Rows.Add(????);
}
我被困在这里将行添加到新数据表中。
答案 0 :(得分:5)
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;
}
答案 1 :(得分:4)
变量声明:
DataTable tempTable = new DataTable();
DataTable slectedFieldsTable = new DataTable();
DataRow newRow;
List<object> list = new List<object>();
在DataTable中添加列:
slectedFieldsTable = new DataTable();
slectedFieldsTable.Columns.Add("Field Name");
slectedFieldsTable.Columns.Add("Field Type");
在DataTable中添加值:
slectedFieldsTable.Rows.Add("1", "AAA");
slectedFieldsTable.Rows.Add("2", "BBB");
slectedFieldsTable.Rows.Add("3", "CCC");
将DataTable转换为List:
foreach (DataRow dr in slectedFieldsTable.Rows)
{
list.Add(dr);
}
在另一个DataTable中添加列:
tempTable.Columns.Add("Field Name", typeof(string));
tempTable.Columns.Add("Field Type", typeof(string));
将List转换为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();
}
答案 2 :(得分:1)
使用CopyToDataTable()方法。 CopyToDataTable
IEnumerable<DataRow> query = TempselectedFieldsTable.AsEnumerable().ToList();
// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();
答案 3 :(得分:0)
试试这个:
foreach (DataRow dr in list)
{
tempTable.Rows.Add(dr);
}
答案 4 :(得分:0)
提供ToDataTable
的答案是一个非常好的开始,但缺少一些关键元素。也就是说,它忽略了List
项属性可能:
ReadOnly
DisplayName
属性DefaultValue
DataColumn
应该知道Nullable
BrowsableAttribute(false)
以下是一种返回DataTable
的扩展方法,可以考虑上述内容,也可以为您的代码提供应用方法。它还使用Interface
从类对象中获取值,而不是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;
}
该方法允许您指定是否应将非Browsable
属性的列添加到DataTable
。如果您愿意,可以完全省略它们,而不是以后隐藏列。
接口证明了按顺序从集合成员获取数据值的方法(作为反射循环的替代方法):
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;
}
}
按照您班级中列出的顺序添加数据值;请务必在添加属性时更新它。反射版仍然存在,所以你可以这样做。
最后,有一些常见的Attribute
没有相关的DataColumn
属性。该方法将这些存储为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();
结果使用上面显示的类列表:
OnHand
和Foo
都会显示DisplayName
,PropA
和PropB
都会被隐藏。最重要的是,为ReadOnly
和Nullable
属性创建的列会相应地起作用。