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

如何在Dapper.Contrib中正确实现表名单数化匹配?

解决Dapper.Contrib自动复数化表名(无需修改POCO类)的问题

你遇到的问题是Dapper.Contrib默认会把POCO类名复数化来生成表名,但你的数据库表是单数命名,而且POCO是自动生成的不能手动修改——用SqlMapperExtensions.TableNameMapper全局配置是最适合你的方案,之前没生效应该是因为设置位置不对,下面给你详细的正确实现方式:

1. 全局设置表名映射委托

SqlMapperExtensions.TableNameMapper是一个静态委托,只需要在应用启动时设置一次,不需要在每次创建数据库连接时重复设置。你之前在连接内部设置可能导致它没在Dapper初始化前生效,所以逻辑不起作用。

2. 实现单数表名的映射逻辑

因为你的POCO类名和数据库表名完全一致,直接返回类的名称即可,不需要复杂的字符串处理。如果以后遇到特殊场景(比如少数表名和类名不一致),也可以在这个委托里扩展判断逻辑。

3. 完整的修改后代码

using Dapper.Contrib.Extensions;
using System.Collections.Generic;
using System.Data.SqlClient;

public class Student {
    public int StudentId {get; set;}
    public string FirstName {get; set;}
    public string LastName {get; set;}
}

class Program {
    static void Main(string[] args) {
        // 全局设置表名映射:直接返回类名(单数),替代默认的复数化逻辑
        SqlMapperExtensions.TableNameMapper = (type) => type.Name;

        var students = new List<Student>() {
            new Student { StudentId = 1, FirstName = "John", LastName = "Doe"},
            new Student { StudentId = 2, FirstName = "Tony", LastName = "Montana"}
        };
        long result;
        // 替换成你的实际连接字符串
        string connString = "your_connection_string_here";
        
        using (var cn = new SqlConnection(connString)) {
            result = cn.Insert(students);
        }
    }
}

4. 验证效果

设置这个委托后,Dapper.Contrib在生成Insert/Update/Delete语句时,会直接使用Student作为表名,而不是默认的Students,这样就不会再抛出Invalid object name 'Students'的异常了。

补充说明

  • 这个方案完全不需要修改自动生成的POCO类,即使以后用Scaffold-DbContext重新生成类,也不会影响配置,完美适配你的开发流程。
  • 如果后续有个别表名和类名不一致的情况,可以在映射委托里添加条件判断,比如:
    SqlMapperExtensions.TableNameMapper = (type) => {
        if (type.Name == "SpecialClass")
            return "SpecialTableName";
        return type.Name;
    };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:27:31