C#中是否有自动将DataRow映射为类对象的方法?
在C#中自动映射DataRow到实体类的方案
当然有!不用再手动写那些重复的空值判断和赋值代码了,C#里不管是自己手动实现反射映射,还是用成熟的第三方库,都能实现类似Spring BeanPropertyRowMapper的自动映射效果。下面给你几种实用的方案:
1. 手动实现反射映射(无额外依赖)
如果不想引入第三方库,可以自己写一个通用的映射工具类,利用反射来匹配列名和实体属性名(默认大小写敏感,你也可以改成不敏感)。比如写一个DataRow的扩展方法:
public static class DataRowExtensions { public static T MapTo<T>(this DataRow row) where T : new() { T obj = new T(); var properties = typeof(T).GetProperties(); foreach (var prop in properties) { // 检查DataRow是否包含该列,且列不为空 if (row.Table.Columns.Contains(prop.Name) && !row.IsNull(prop.Name)) { try { // 转换数据类型并赋值 var value = Convert.ChangeType(row[prop.Name], prop.PropertyType); prop.SetValue(obj, value); } catch (Exception ex) { // 可以根据需要处理类型转换异常,比如日志记录 Console.WriteLine($"映射属性 {prop.Name} 时出错: {ex.Message}"); } } } return obj; } }
使用起来就非常简单了,直接调用扩展方法:
Scoring scoring = dr.MapTo<Scoring>();
这个方法会自动匹配实体类的属性名和DataRow的列名,处理空值,还做了类型转换的异常捕获,基本能覆盖大部分场景。
2. 使用第三方库(比如AutoMapper)
如果项目已经在用AutoMapper,或者想要更强大的映射能力(比如自定义字段映射、类型转换规则),AutoMapper可以轻松搞定DataRow到实体的映射。
首先需要配置映射(一般在项目启动时配置一次):
var config = new MapperConfiguration(cfg => { cfg.CreateMap<DataRow, Scoring>(); // 如果列名和属性名不一致,可以手动指定映射 // cfg.CreateMap<DataRow, Scoring>().ForMember(dest => dest.EntityName, opt => opt.MapFrom(src => src["Entity_Name"])); }); IMapper mapper = config.CreateMapper();
然后映射的时候直接用:
Scoring scoring = mapper.Map<Scoring>(dr);
AutoMapper会自动处理空值和类型转换,还支持很多高级配置,比如忽略某些属性、自定义转换逻辑等,非常灵活。
3. 高性能替代方案:FastMember
如果你的场景需要处理大量数据映射,追求更好的性能,可以用FastMember这个库替代原生反射,它的性能比原生反射提升不少:
using FastMember; public static T MapToFast<T>(this DataRow row) where T : new() { T obj = new T(); using (var accessor = TypeAccessor.Create(typeof(T))) { foreach (DataColumn column in row.Table.Columns) { var colName = column.ColumnName; if (!row.IsNull(colName)) { accessor[obj, colName] = row[colName]; } } } return obj; }
总的来说,这些方案都能帮你省去手动映射的麻烦,完全可以替代Spring里的BeanPropertyRowMapper的功能,根据你的项目需求选择合适的方式就好。
内容的提问来源于stack exchange,提问作者xMilos
相关产品推荐
相关产品推荐

