C#如何通过反射读取属性绑定的Data Annotation注解
C#读取属性标注注解的实现方案
首先直接回答两个核心问题:
- 单个属性支持标注多个注解,只要对应注解的
AttributeUsage配置没有禁用多实例,你示例中Id属性同时标注[PrimaryKey]和[Identity]的写法完全合法。 - 读取属性上的注解直接通过反射提供的
GetCustomAttributes系列方法即可实现,不需要额外依赖。
具体用法
你在遍历PropertyInfo的循环中,可以直接调用以下方法完成注解判断和读取:
- 校验是否存在指定类型的注解:调用
GetCustomAttribute<注解类型>(),返回值非空即表示存在对应注解 - 获取属性上的所有注解:调用
GetCustomAttributes(inherit: false),返回值为该属性上所有注解的实例数组
注意:使用反射相关方法需要先引入
System.Reflection命名空间;C#中[PrimaryKey]这类写法是语法糖,实际对应的类型名为PrimaryKeyAttribute,泛型调用时写完整类名即可。如果是低于.NET Framework 4.5的老旧环境,可以用非泛型写法Attribute.GetCustomAttribute(prop, typeof(PrimaryKeyAttribute)) != null实现相同判断效果。
整合注解读取后的代码示例
using System.Reflection; // 必须引入的命名空间 var type = typeof(TValue); var properties = type.GetProperties(); var name = type.Name; string[] propertySQLstring = new string[properties.Length]; string[] valueSQLstring = new string[properties.Length]; for (int i = 0; i < properties.Length; i++) { var prop = properties[i]; // 注解读取逻辑 // 判断是否为主键 bool isPrimaryKey = prop.GetCustomAttribute<PrimaryKeyAttribute>() != null; // 判断是否为自增列 bool isIdentity = prop.GetCustomAttribute<IdentityAttribute>() != null; // 判断是否为外键 bool isForeignKey = prop.GetCustomAttribute<ForeignKeyAttribute>() != null; // 如果需要获取所有标注的注解,取消注释下一行即可 // var allAttributesOnProp = prop.GetCustomAttributes(inherit: false); // 原有SQL拼接逻辑,可结合上面的注解标记做调整,比如自增主键插入时可跳过 var propValue = prop.GetValue(value); if (i + 1 == properties.Length) { propertySQLstring[i] = prop.Name; valueSQLstring[i] = propValue?.GetType() != typeof(string) ? propValue?.ToString() : $"'{propValue}'"; } else { propertySQLstring[i] = prop.Name + ","; valueSQLstring[i] = propValue?.GetType() != typeof(string) ? propValue?.ToString() + ',' : $"'{propValue}', "; } }
你可以根据自己的业务需求,基于读取到的注解标记调整SQL生成逻辑,比如自增主键在INSERT语句中不需要传入值、外键列做关联校验等。
内容的提问来源于stack exchange,提问作者Zerostar362
相关产品推荐
相关产品推荐

