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
相关产品推荐
相关产品推荐

