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

如何用Dapper.Contrib+FluentMap更新含自定义名称标识列的实体?

问题根因

你使用的ORM(大概率是Dapper Extensions/Dapper Contrib/轻量级EF)执行更新操作时,默认将名为Id的主键属性映射到数据库id列作为更新条件,你配置的列映射规则未被ORM正确加载或者未关联主键规则,导致生成的SQL语句用了不存在的id列。

解决方案

方案1:直接用特性声明映射(适配绝大多数ORM,最简便)

在Id属性上同时添加[Column]特性指定数据库列名,自增主键额外添加[DatabaseGenerated]特性即可:

[Table("Business")]
public class Business {
    [Key]
    [Column("BusinessId")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    // 其余属性省略
}

配置完成后ORM执行_db.Update(business)时会自动将Id属性对应到BusinessId列生成更新条件,不会再报列不存在的错误。

方案2:修正Fluent API映射配置并加载

如果你更偏好Fluent API的映射方式(即你写的EntityMap类),需要完成两个配置:

  1. 在映射中明确标记Id为主键,同时绑定列名:
public class BusinessMap : EntityMap<Business>
{
    public BusinessMap()
    {
        Map(x => x.Id).ToColumn("BusinessId").Key(KeyType.Identity);                
    }
}
  1. 程序启动时注册映射类所在的程序集,让ORM可以扫描到你的映射规则:
// 以Dapper Extensions为例
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { typeof(BusinessMap).Assembly });

方案3:全局配置主键命名规则(适合批量实体同规则场景)

如果你的项目中所有实体都遵循「属性名Id对应数据库表名+Id列」的规则,可以直接配置全局映射规则,无需每个实体单独配置:

// 自定义全局Mapper,以Dapper Extensions为例
public class CustomAutoMapper<T> : PluralizedAutoClassMapper<T> where T : class
{
    public CustomAutoMapper()
    {
        var idProp = typeof(T).GetProperty("Id");
        if (idProp != null)
        {
            Map(idProp).ToColumn($"{typeof(T).Name}Id").Key(KeyType.Identity);
        }
    }
}

// 程序启动时设置全局使用自定义Mapper
DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomAutoMapper<>);
DapperExtensions.DapperExtensions.SqlDialect = new SqlServerDialect();

配置完成后所有带Id属性的实体都会自动匹配对应表名+Id的数据库列,后续新增实体也不需要单独做主键映射。


内容的提问来源于stack exchange,提问作者Maccurt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 09:09:01