Dapper 默认靠属性名和列名完全一致来自动映射,一旦不一致(比如数据库用
create_time,C# 里写成 CreateTime),就会映射失败或值为空。解决方法不复杂但容易忽略,核心是让 Dapper “知道”哪个列对应哪个属性。
SQL 中用 AS 别名最直接
查询时在 SQL 里把列名重命名为属性名,Dapper 就能自动识别:
SELECT user_id AS UserId, user_name AS UserName FROM users搭配
Query<user>()</user>即可正常映射,无需改模型或加配置 插入/更新操作也适用:用
INSERT INTO ... VALUES (@UserId, @UserName),参数名对上属性名就行
给属性加 [Column] 特性(推荐用于长期维护项目)
在实体类属性上标注数据库真实列名,Dapper(配合 Dapper.Contrib 或自定义 TypeMap)能识别:
[Column("create_time")] public DateTime CreateTime { get; set; }
[Column("user_id")] public int UserId { get; set; }
注意:纯 Dapper 查询默认不读取 [Column],需搭配
SqlMapper.SetTypeMap或使用 Dapper.Contrib 扩展才生效
运行时动态设置 TypeMap(适合统一管理多模型)
在应用启动时(如 Program.cs 或 Startup.cs),批量为带
[Table]的类注册自定义映射逻辑: 遍历所有模型类型,检查每个属性是否有
[Column("xxx")]
用 SqlMapper.SetTypeMap(type, new CustomPropertyTypeMap(...))注册 之后所有
Query<t>()</t>、
Insert()等操作都会按 Column 特性自动匹配列名
用 map 参数手动指定(适合临时或特殊查询)
调用
Query时传入
map委托,灵活控制字段到属性的绑定:
connection.Query<userdto>(sql, map: m => m.MapProperty(u => u.UserId).ToColumn("user_id"))</userdto>
适用于 DTO 映射、字段名差异大、或只在某处需要特殊处理的场景
不侵入模型,也不影响全局行为
基本上就这些。日常开发中,小项目用 AS 别名最快;中大型项目建议统一加
[Column]并配 TypeMap,既清晰又省心。
