.NET Framework4.5下AutoMapper映射IDataReader如何免逐列配置?
针对你的问题,在.NET Framework 4.5环境下没法用Automapper.Data的话,确实有几个办法能帮你省去逐列写映射规则的麻烦,下面给你详细说几个可行的方案:
方案1:自己实现一个通用的反射映射工具
这个思路是利用.NET的反射机制,自动匹配IDataReader的列名和DTO类的属性名,完成映射。优点是完全自定义,不依赖第三方库,适配你的环境。
你可以写一个静态扩展类,比如这样:
public static class DataReaderMapper { public static List<T> MapToList<T>(this IDataReader reader) where T : new() { var result = new List<T>(); var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); while (reader.Read()) { var item = new T(); foreach (var prop in properties) { // 检查DataReader中是否存在对应列名(忽略大小写) if (!reader.HasColumn(prop.Name)) continue; var value = reader[prop.Name]; // 处理DBNull的情况,同时兼容Nullable类型 if (value != DBNull.Value) { var targetType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; var convertedValue = Convert.ChangeType(value, targetType); prop.SetValue(item, convertedValue); } } result.Add(item); } return result; } // 辅助方法:检查DataReader是否包含指定列 private static bool HasColumn(this IDataReader reader, string columnName) { for (int i = 0; i < reader.FieldCount; i++) { if (reader.GetName(i).Equals(columnName, StringComparison.OrdinalIgnoreCase)) return true; } return false; } }
使用的时候就很简单了:
using (var reader = command.ExecuteReader()) { var myDtos = reader.MapToList<MyDto>(); }
这个工具会自动匹配属性名和列名,还处理了DBNull和Nullable类型的转换,基本能覆盖大部分常规场景。
方案2:给AutoMapper添加自动映射扩展
如果你还是想继续用AutoMapper,不想放弃它的其他功能,可以自己写一个扩展方法,通过反射自动生成所有ForMember的配置,不用手动逐行写。
比如这样:
public static class AutoMapperDataReaderExtensions { public static IMappingExpression<IDataReader, TDestination> AutoMapColumns<TDestination>(this IMappingExpression<IDataReader, TDestination> expression) where TDestination : class { var properties = typeof(TDestination).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties) { expression.ForMember(prop.Name, opt => opt.MapFrom(rdr => rdr[prop.Name] != DBNull.Value ? Convert.ChangeType(rdr[prop.Name], Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType) : null)); } return expression; } }
然后配置的时候就可以这样用:
cfg.CreateMap<IDataReader, MyDto>().AutoMapColumns();
这样一行代码就代替了所有手动的ForMember配置,原理是通过反射遍历DTO的属性,自动生成每个属性的映射规则,和你手动写的逻辑一致,但不用重复劳动。
方案3:改用Dapper(推荐)
如果你的项目还没绑定死AutoMapper,强烈推荐试试Dapper。它是轻量级的ORM,完全支持.NET Framework 4.5,而且天生就支持把IDataReader(或者直接从数据库查询)自动映射到你的DTO类,根本不用写任何映射配置。
用法非常简单:
首先通过NuGet安装Dapper包,然后:
using (var connection = new SqlConnection("你的连接字符串")) { var myDtos = connection.Query<MyDto>("SELECT Id, Name, Text FROM YourTable").ToList(); }
Dapper会自动匹配列名和属性名(支持忽略大小写),处理DBNull和类型转换,性能还非常好,比自己写反射工具或者AutoMapper都高效。
内容的提问来源于stack exchange,提问作者Pupkin
相关产品推荐
相关产品推荐

