Slapper.AutoMapper仅返回单个对象而非列表,求代码排查及Dapper映射方案
嘿,从Java转C#确实得适应不少生态差异,我来帮你梳理这两个问题:
一、Dapper调用存储过程获取POCO列表的常见问题排查
虽然你没贴出具体代码,但根据日常开发里遇到的情况,这类场景容易踩这些坑:
- 没指定存储过程类型:Dapper默认把传入的语句当成普通SQL执行,如果你调用存储过程时没加
commandType: CommandType.StoredProcedure,就会找不到对应的存储过程。正确的调用姿势是:using var connection = new SqlConnection("your_connection_string"); var result = connection.Query<A>("YourStoredProcName", commandType: CommandType.StoredProcedure).ToList(); - 属性与列名不匹配:Dapper默认是大小写不敏感的名称匹配,但如果数据库列名和POCO属性名差异较大(比如库中是
user_id,POCO是UserId),没做映射的话会导致属性值为null。解决方法要么给SQL结果加别名,要么用Dapper的ColumnAttribute标注:public class A { [Column("user_id")] public int UserId { get; set; } } - 参数传递出错:如果存储过程需要参数,你没传或者参数名和存储过程里的参数名不匹配,会导致执行失败或者返回空结果。比如存储过程需要
@UserId参数,你就得传对应的参数对象:var parameters = new { UserId = 123 }; var result = connection.Query<A>("YourStoredProcName", parameters, commandType: CommandType.StoredProcedure).ToList(); - 多结果集处理错误:如果存储过程返回多个结果集,直接用
Query<T>只会读取第一个结果集。要是你需要的是第二个或后续的,得用QueryMultiple来处理:using var multi = connection.QueryMultiple("YourStoredProcName", commandType: CommandType.StoredProcedure); var listA = multi.Read<A>().ToList(); var listB = multi.Read<B>().ToList(); - 连接资源管理不当:虽然Dapper会自动打开未打开的连接,但最好用
using包裹连接对象,确保用完后及时释放资源,避免连接池耗尽。
二、替代Slapper.Automapper的现代POCO映射方案
确实,Slapper.Automapper现在已经没多少人用了,现在C#生态里有不少更灵活、维护更活跃的映射工具可以配合Dapper:
- Dapper内置映射:其实Dapper本身就支持大部分基础映射需求,除了上面提到的
ColumnAttribute,还可以通过CustomTypeMap全局配置映射规则,比如处理复杂类型或者自定义名称映射,完全不需要额外依赖。 - Mapster:这是目前非常火的高性能映射库,支持自动映射、自定义规则、投影等,配置也很简洁。配合Dapper的话,你可以让Dapper返回动态对象,再用Mapster转成POCO:
它还支持编译映射,性能几乎和手动写的映射代码一样快。var dynamicResults = connection.Query("YourStoredProcName", commandType: CommandType.StoredProcedure); var pocoList = dynamicResults.Adapt<List<A>>(); - AutoMapper:老牌的全功能映射库,适合复杂的映射场景,比如多层DTO转换、嵌套对象映射等。你可以通过Profile定义映射规则,然后结合Dapper使用:
var config = new MapperConfiguration(cfg => { cfg.CreateMap<dynamic, A>() .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.user_id)); }); var mapper = config.CreateMapper(); var result = connection.Query("YourStoredProcName", commandType: CommandType.StoredProcedure) .Select(mapper.Map<A>) .ToList(); - ExpressMapper:轻量级的映射库,基于表达式树实现,性能不错,配置简单,适合中小型项目的简单映射需求。
如果你的场景比较简单,Dapper内置的映射就足够用;如果需要复杂的跨层对象转换,Mapster或AutoMapper会是更合适的选择。
内容的提问来源于stack exchange,提问作者SNabi
相关产品推荐
相关产品推荐

