问题描述
我已经创建了一个将 List 转换为 Datatble 的函数。但是我需要自定义此函数,以便该方法将具有仅在转换为数据表时才考虑的列表属性(例如:名称、年龄)的附加参数。另外我想保持列的顺序与它们在属性列表中的顺序相同。示例 - 我正在传递列表(具有不同属性名称、年龄、出生日期、地点的客户)和要转换的属性列表,即列表(名称,年龄)。此外,我想将名称的数据表列标题重命名为“人名”和年龄作为“人年龄”。谁能帮助我如何实现这一点。此外,您可以提出更好的逻辑来实现要求。
public DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
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++)
{
values[i] = Props[i].GetValue(item,null);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
解决方法
我建议您更改方法以采用 Dictionary<string,string>
,它充当从您感兴趣的属性到其映射名称的映射。然后用这个来过滤对象的属性,建立数据表
public static DataTable ToDataTable<T>(List<T> items,Dictionary<string,string> properties)
{
DataTable dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => properties.ContainsKey(p.Name)).ToArray();
foreach (PropertyInfo prop in Props)
{
//Setting column names as Property names
dataTable.Columns.Add(properties[prop.Name]);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
values[i] = Props[i].GetValue(item,null);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
然后您可以执行以下操作:
var props = new Dictionary<string,string>
{
["Name"] = "Person Name",["Age"] = "Person Age"
};
var dt = ToDataTable(people,props);
现场示例:https://dotnetfiddle.net/7XkJvV
,MoreLINQ 包已经有一个适用于任何 IEnumerable<T>
的 ToDataTable 方法。您可以使用 LINQ 的 Select
以您想要的任何方式塑造数据,然后使用 ToDataTable
将其转换为数据表:
var table= customers.Select (customer => new {
customer.Name,customer.DOB,Age=(DateTime.Today-customer.DOB).Days/365
})
.ToDataTable();
ToDataTable
有一个重载,允许您通过表达式指定要使用的属性:
var table=customers.ToDataTable(new[]{ c=>c.Name,c=>c.DOB });
另一个允许您填充已创建和配置的表。来自 the unit tests 之一:
var dt = new DataTable();
var columns = dt.Columns;
columns.Add("Column1",typeof(int));
columns.Add("Value",typeof(string));
columns.Add("Column3",typeof(int));
columns.Add("Name",typeof(string));
var vars = Environment.GetEnvironmentVariables()
.Cast<DictionaryEntry>()
.ToArray();
vars.Select(e => new { Name = e.Key.ToString(),Value = e.Value.ToString() })
.ToDataTable(dt,e => e.Name,e => e.Value);
带空格的列
之后您可以更改 DataColumn.ColumnName,但也许更好的解决方案是设置 Caption 属性。 Caption
的默认值为 ColumnName
。带有空格的名称几乎肯定是为了显示目的。
最好不要修改 ColumnName
,这样您就可以按名称识别列,并将显示标题更改为您需要的任何内容。
例如:
var personColumns=new[]{"Name","Age"};
foreach(DataColumn column in table.Columns)
{
column.Caption = $"Person {column.ColumnName}";
}