You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Dapper自动映射含只读属性的C#继承类对象?

解决Dapper映射只读构造属性的问题

Dapper默认会优先选择参数与查询列名匹配的构造函数,而非无参构造函数,这正好解决你只读属性(ID、SomeKey)无法自动映射的问题,无需手动实例化后再映射所有属性。

核心思路

  1. 确保DerivedEntity的构造函数参数名与存储过程返回的列名一致(大小写不敏感)
  2. Dapper会自动调用该构造函数初始化BaseEntity的只读属性
  3. 其余可写属性由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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:27:40