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

Dapper TableAttribute运行时配置,如何通过AppSettings读取表名?

解决Dapper.Contrib TableAttribute无法识别非const字符串的问题

首先得明确为什么会失效:C#要求特性(Attribute)的构造函数参数必须是编译时常量,而你用的静态属性是运行时才会计算值的,所以Dapper.Contrib的TableAttribute根本没法在编译阶段获取到表名,自然就失效了。

下面给你两个可行的解决方案,按推荐程度排序:

方案1:使用Dapper.Contrib的动态表名映射委托

这是最直接且侵入性最低的方案,不需要修改实体类的Attribute,而是在应用启动时配置全局的表名映射规则:

// 在应用初始化的地方(比如Program.cs、Startup.cs的配置阶段)执行
using Dapper.Contrib.Extensions;
using System.Configuration;

// 从AppSettings读取表名
var archivoClienteTableName = ConfigurationManager.AppSettings["TABLE_ARCHIVO_CLIENTE"];

// 注册表名映射逻辑
SqlMapperExtensions.TableNameMapper = (type) =>
{
    // 针对特定实体指定表名
    if (type == typeof(ArchivoCliente))
    {
        return archivoClienteTableName;
    }
    // 其他实体的默认处理:比如用类名作为表名(和Dapper.Contrib默认行为一致)
    return type.Name;
};

这样配置后,Dapper.Contrib在操作ArchivoCliente实体时,会自动使用你从AppSettings读取的表名,完全替代了TableAttribute的作用。

方案2:自定义Dapper类型映射(脱离Dapper.Contrib的Attribute)

如果你不想依赖Dapper.Contrib的扩展,也可以直接用Dapper核心库的自定义类型映射来指定表名:

using Dapper;
using System.Configuration;
using System.Reflection;

var tableName = ConfigurationManager.AppSettings["TABLE_ARCHIVO_CLIENTE"];

// 自定义类型映射,指定表名和属性映射
SqlMapper.SetTypeMap(typeof(ArchivoCliente), new CustomTypeMap(
    typeof(ArchivoCliente),
    tableName,
    (type, columnName) => type.GetProperty(columnName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance)
));

// 自定义CustomTypeMap类实现ITypeMap
public class CustomTypeMap : ITypeMap
{
    private readonly Type _type;
    private readonly string _tableName;
    private readonly Func<Type, string, PropertyInfo> _propertySelector;

    public CustomTypeMap(Type type, string tableName, Func<Type, string, PropertyInfo> propertySelector)
    {
        _type = type;
        _tableName = tableName;
        _propertySelector = propertySelector;
    }

    public ConstructorInfo FindConstructor(string[] names, Type[] types)
    {
        return _type.GetConstructor(Type.EmptyTypes);
    }

    public ConstructorInfo FindExplicitConstructor()
    {
        return _type.GetConstructor(Type.EmptyTypes);
    }

    public PropertyInfo GetProperty(string columnName)
    {
        return _propertySelector(_type, columnName);
    }

    public IEnumerable<PropertyInfo> GetProperties()
    {
        return _type.GetProperties();
    }

    public string GetTableName()
    {
        return _tableName;
    }

    public ConstructorInfo GetConstructor()
    {
        return _type.GetConstructor(Type.EmptyTypes);
    }
}

这个方案更灵活,但需要自己实现ITypeMap接口,适合需要更复杂映射规则的场景。


内容的提问来源于stack exchange,提问作者PreguntonCojoneroCabrón

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:43:40