如何通过指定属性名称将通用对象列表转换为DataTable?-C#



我创建了一个函数,用于将List转换为Datatble。但我需要自定义这个函数,这样方法就有了List属性的额外参数(例如:Name,Age(,这些参数只在转换为datatble时才会考虑。此外,我希望保持列的顺序与它们在属性列表中的顺序相同。示例-我正在传递List(具有不同属性的客户名称、年龄、出生日期、地点(和要转换的属性列表,即List(名称、年龄(;人名";以及Age为";人的年龄";。有人能帮我怎么做到这一点吗。此外,您还可以提出更好的逻辑来实现需求。

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包已经有一个ToDataTable方法,可以在任何IEnumerable<T>上工作。您可以使用LINQ的Select以任何方式对数据进行整形,然后使用ToDataTable:将其转换为DataTable

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 });

另一个允许您填充已经创建和配置的表。来自一个单元测试:

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}";
}

最新更新