如何使用Dapper自动映射含只读属性的C#继承类对象?
解决Dapper映射只读构造属性的问题
Dapper默认会优先选择参数与查询列名匹配的构造函数,而非无参构造函数,这正好解决你只读属性(ID、SomeKey)无法自动映射的问题,无需手动实例化后再映射所有属性。
核心思路
- 确保
DerivedEntity的构造函数参数名与存储过程返回的列名一致(大小写不敏感) - Dapper会自动调用该构造函数初始化
BaseEntity的只读属性 - 其余可写属性由Dapper自动完成映射,多映射场景只需调整拆分规则
代码示例
实体类定义(确保构造函数参数匹配列名)
public class BaseEntity { public int ID { get; } public int SomeKey { get; } public Example ExampleProperty { get; set; } protected BaseEntity(int id, int someKey) { ID = id; SomeKey = someKey; } } public class DerivedEntity : BaseEntity { public string AnotherProperty { get; set; } // 其他业务属性... // 构造函数参数名与数据库返回列名(ID、SomeKey)对应 public DerivedEntity(int id, int someKey) : base(id, someKey) { } } public class Example { // Example类的构造或属性定义 public Example(int gameKey, int id, int playerId) { // 初始化逻辑 } }
调整后的Dapper查询代码
// 注意:splitOn需要指定第二个类型(Example)对应的第一个列名,而非属性名 results = (await sqlcon.QueryAsync<DerivedEntity, Example, DerivedEntity>( sql: "my_stored_procedure", map: (derived, example) => { // 若Example由查询结果自动映射,直接赋值;若需手动构造,使用已初始化的只读属性 derived.ExampleProperty = new Example(derived.SomeKey, derived.ID, play.PlayerID); return derived; }, param: parameters, splitOn: "ExampleFirstColumn", // 替换为Example类型对应的第一个数据库列名 commandType: CommandType.StoredProcedure, commandTimeout: 1000)).ToList();
关键注意事项
- 若构造函数参数名与列名不匹配,可在参数上添加
[Column("列名")]特性显式映射 splitOn参数是用来拆分结果集列的标记,必须是数据库返回的列名,而非实体属性名- Dapper会自动处理构造函数注入,无需额外配置即可初始化只读属性
内容的提问来源于stack exchange,提问作者angrycowboysfan
相关产品推荐
相关产品推荐

