【C#】DataTable转换为实体集

Model字段名称必须与数据库字段名称相同

private List<T> TableToList<T>(DataTable dt) where T : class, new()
{
    Type type = typeof(T);
    List<T> list = new List<T>();

    foreach (DataRow row in dt.Rows)
    {
        PropertyInfo[] properties = type.GetProperties();
        T model = new T();
        foreach (PropertyInfo p in properties)
        {
            object value = row[p.Name];
            if (value == DBNull.Value)
            {
                p.SetValue(model, "", null);
            }
            else
            {
                if (value is decimal)
                {
                    p.SetValue(model, Convert.ToInt32(value), null);
                }
                else
                {
                    p.SetValue(model, value, null);
                }
            }
        }
        list.Add(model);
    }
    return list;
}

使用

string sql = "select * from student";

DataTable dt = SqlHelper.ExecuteDataTable(sql);

List<Student> list = TableToList<Student>(dt);

 

<think>我们有一个任务:将C#中的List集合转换DataTable对象。 根据引用[1]中提供的方法,我们可以使用反射来获取List中对象的属性,然后创建DataTable的列,再遍历List中的每个对象,将其属性值添加到DataTable的行中。 注意:引用[1]中的方法是一个扩展方法,它扩展了IList<TSource>类型。 步骤: 1. 创建一个DataTable,并指定表名(可以使用类型名称)。 2. 获取泛型类型TSource的所有公共实例属性。 3. 遍历这些属性,为每个属性在DataTable中创建对应的列。注意处理可空类型。 4. 遍历List中的每个元素,对于每个元素,获取其所有属性值,然后将这些值作为一行添加到DataTable中。 引用[1]中的代码已经提供了一个完整的实现,我们可以直接使用它。 但是,我们需要注意:如果List为空,那么我们应该返回一个只有列结构的空DataTable。 另外,引用[3]提到了DataTable实体,但我们现在需要的是List转DataTable,所以主要参考引用[1]。 下面我们写出这个扩展方法:</think>在 C# 中将 `List<T>` 转换为 `DataTable` 可通过反射动态创建表结构并填充数据。以下是实现方法和注意事项: ### 实现代码 ```csharp using System; using System.Collections.Generic; using System.Data; using System.Reflection; public static class ListExtensions { public static DataTable ToDataTable<T>(this IList<T> data) { DataTable dataTable = new DataTable(typeof(T).Name); // 创建列 PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo prop in props) { // 处理可空类型 Type colType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; dataTable.Columns.Add(prop.Name, colType); } // 填充数据行 foreach (T item in data) { var values = new object[props.Length]; for (int i = 0; i < props.Length; i++) { values[i] = props[i].GetValue(item, null) ?? DBNull.Value; } dataTable.Rows.Add(values); } return dataTable; } } ``` ### 使用示例 ```csharp // 定义实体类 public class Person { public int Id { get; set; } public string Name { get; set; } public DateTime? BirthDate { get; set; } // 可空类型 } // 转换操作 List<Person> people = new List<Person> { new Person { Id = 1, Name = "Alice", BirthDate = new DateTime(1990, 5, 15) }, new Person { Id = 2, Name = "Bob", BirthDate = null } }; DataTable personTable = people.ToDataTable(); ``` ### 关键说明 1. **动态列创建**:通过反射获取 `T` 类的公共属性自动生成列 2. **可空类型处理**:`Nullable.GetUnderlyingType()` 确保正确识别值类型 3. **空值处理**:将 `null` 转换为 `DBNull.Value` 避免插入异常 4. **表名设置**:使用泛型类型名称作为默认表名(可通过 `TableName` 属性修改) ### 性能优化建议 - 对静态类型可缓存 `PropertyInfo[]` 减少反射开销 - 大型数据集建议使用 `SqlBulkCopy` 直接导入数据库 - 需要特殊列映射时,可重载方法添加自定义列配置参数 > 此方法适用于中小型数据集,超大规模数据($>10^5$ 条)需考虑分块处理或专用 ETL 工具[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreAmbWang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值