C# .NET Framework 5中通过列索引循环填充DataTable的优化问询
实现按列索引循环填充DataTable的方法
针对列数较多的场景,推荐两种通用的循环填充方案,无需手动逐个指定属性:
方案一:基于列名匹配的反射填充(推荐)
利用DataTable列名与实体属性名的对应关系,通过反射批量获取属性值,按列索引循环赋值。如果担心反射性能,可提前缓存属性信息。
基础版本
foreach (var entity in EDBRecList) { DataRow row = dataTable.NewRow(); for (int i = 0; i < dataTable.Columns.Count; i++) { DataColumn column = dataTable.Columns[i]; // 根据列名获取实体对应属性 var property = typeof(EDBRec).GetProperty(column.ColumnName); if (property != null) { var value = property.GetValue(entity); // 将null转为DBNull,避免DataTable报错 row[i] = value ?? DBNull.Value; } else { // 列名与属性不匹配时的默认处理 row[i] = DBNull.Value; } } dataTable.Rows.Add(row); }
性能优化版本(缓存属性)
// 提前缓存实体属性,避免每次循环重复反射 var propertyCache = typeof(EDBRec).GetProperties() .ToDictionary(p => p.Name, p => p); foreach (var entity in EDBRecList) { DataRow row = dataTable.NewRow(); for (int i = 0; i < dataTable.Columns.Count; i++) { DataColumn column = dataTable.Columns[i]; if (propertyCache.TryGetValue(column.ColumnName, out var property)) { var value = property.GetValue(entity); row[i] = value ?? DBNull.Value; } else { row[i] = DBNull.Value; } } dataTable.Rows.Add(row); }
方案二:基于属性与列顺序匹配的填充
如果实体属性的声明顺序和DataTable的列创建顺序完全一致,可以直接按索引一一对应赋值:
// 提前获取实体属性数组 var entityProperties = typeof(EDBRec).GetProperties(); foreach (var entity in EDBRecList) { DataRow row = dataTable.NewRow(); for (int i = 0; i < dataTable.Columns.Count; i++) { if (i < entityProperties.Length) { var value = entityProperties[i].GetValue(entity); row[i] = value ?? DBNull.Value; } else { row[i] = DBNull.Value; } } dataTable.Rows.Add(row); }
注意事项
- 确保DataTable的列名(或顺序)与实体属性严格对应,否则会出现赋值错误
- 必须将实体属性的
null值转为DBNull.Value,否则DataTable会抛出异常 - 反射方案的性能足够应对大多数场景,若需极致性能可考虑使用表达式树编译替代反射
内容的提问来源于stack exchange,提问作者Владимир
相关产品推荐
相关产品推荐

