Dapper 不自动映射 DTO,因其设计轻量、显式、高性能,仅支持字段名匹配的简单映射;AutoMapper 负责复杂对象转换,二者需手动协作,推荐先用 Dapper 查询再由 AutoMapper 映射。
直接用 Dapper 查询数据库后,结果默认是 IDataReader 或动态对象(如 dynamic),它本身不提供自动映射到 DTO 的能力。Dapper 也不内置类似 AutoMapper 的对象映射逻辑 —— 所以“Dapper 自动映射 DTO”其实是靠你手动调用 AutoMapper,而不是 Dappe
r 主动触发它。
Dapper 的设计哲学是轻量、显式、高性能。它只负责把 SQL 结果按字段名(或列序)映射到强类型对象的 同名 public 属性 上,不介入业务层的转换逻辑(比如属性重命名、类型转换、嵌套对象组装、条件映射等)。AutoMapper 则专注在对象到对象的复杂转换上,两者职责不同,天然互补但需手动桥接。
这是最常用、最易调试、也最符合分层原则的方式:先用 Dapper 获取领域模型(如 Entity)或匿名对象,再交给 AutoMapper 转成 DTO。
mapper.Map(entity)
conn.Query("SELECT Id, Name FROM Users")
避免重复写“查 + 映射”,可封装通用方法:
public async TaskQuerySingleAsync ( string sql, object param = null) where TEntity : class { var entity = await _connection.QuerySingleAsync (sql, param); return _mapper.Map (entity); }
这样业务代码就变成:var userDto = await handler.QuerySingleAsync
Query 中传 DTO 类型,除非字段 100% 匹配(比如 DTO 没有构造函数参数、没私有 setter、所有属性名和 SQL 列名一致)CreateMap() ),否则运行时报错UserDto.Profile),Dapper 原生不支持自动展开;此时要么用 Query 手动组合,要么改用 AutoMapper 的 ProjectTo(配合 EF Core)—— Dapper 不支持 ProjectTo基本上就这些。Dapper 和 AutoMapper 不是“绑定关系”,而是“协作关系”:一个管快读,一个管巧转。用好它们的关键是明确分工,不越界,不强求自动化。