C#自定义特性-SQL
语法
原则
自定义特性必须继承自System.Attribute类;
AttributeUsage属性来指定特性的使用范围和是否允许重复等;
在特性类中定义属性,这些属性将用于存储特性值。
示例
using System;// 定义一个自定义特性类
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class CustomAttribute : Attribute
{// 特性属性public string Description { get; set; }public int Version { get; set; }// 特性构造函数public CustomAttribute(string description, int version){Description = description;Version = version;}
}// 使用自定义特性
[Custom("This is a sample class", 1)]
public class SampleClass
{[Custom("This is a sample method", 1)]public void SampleMethod(){// 方法实现}
}class Program
{static void Main(){// 获取SampleClass类的特性信息var classAttributes = typeof(SampleClass).GetCustomAttributes(typeof(CustomAttribute), false);foreach (CustomAttribute attr in classAttributes){Console.WriteLine($"Class Description: {attr.Description}, Version: {attr.Version}");}// 获取SampleMethod方法的特性信息var methodAttributes = typeof(SampleClass).GetMethod("SampleMethod").GetCustomAttributes(typeof(CustomAttribute), false);foreach (CustomAttribute attr in methodAttributes){Console.WriteLine($"Method Description: {attr.Description}, Version: {attr.Version}");}}
}
AttributeUsage中的AllowMultiple属性默认值为false,它决定同种特性类型的实例能否在同一个目标上多次使用,比如在类中的同一个属性上。
特性声明代码
using System;
using System.Reflection;namespace Model.Common
{/// <summary>/// 用于生成SQLServer数据库查询的like条件/// </summary>[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]public class SqlLikeAttribute : Attribute{/// <summary>/// 数据库字段名/// </summary>public string FieldName { get; set; }public SqlLikeAttribute(string fidleName){FieldName = fidleName;}}/// <summary>/// 用于生成SQLServer数据库查询的>、>=、<、<==、=条件/// </summary>[AttributeUsage(AttributeTargets.Property,AllowMultiple = false)]public class SqlRangeAttribute: Attribute{/// <summary>/// 数据库字段名/// </summary>public string FieldName { get; set; }/// <summary>/// 取值范围:>、>=、<、<==、=/// </summary>public string Range { get; set; }public SqlRangeAttribute(string fidleName, string range){FieldName = fidleName;Range= range;}}/// <summary>/// 用于生成SQLServer数据库查询的between条件/// </summary>[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]public class SqlBetweenAttribute : Attribute{/// <summary>/// 数据库字段名/// </summary>public string FieldName { get; set; }/// <summary>/// 查询条件实体中的另一个字段名/// </summary>public string AnotherFieldName { get; set; }/// <summary>/// 是否是开始/// </summary>public bool IsStart { get; set; }public Object Value { get; set; }public SqlBetweenAttribute(string fidleName, string anotherFieldName, bool start = true){FieldName = fidleName;AnotherFieldName = anotherFieldName;IsStart = start;}}/// <summary>/// 用于生成SQLServer数据库查询的条件,有SqlIgnoreAttribute修饰的属性直接忽略掉/// </summary>[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]public class SqlIgnoreAttribute : Attribute{}/// <summary>/// 测试/// </summary>public class AttributeTest{public static void Test(){TestModel testModel = new TestModel(){ID = 1,Name = "test",Begin = DateTime.Now,End = DateTime.Now.AddDays(1),};Type type = testModel.GetType();PropertyInfo[] infos = type.GetProperties();foreach (PropertyInfo info in infos){SqlBetweenAttribute attr = (SqlBetweenAttribute)info.GetCustomAttribute(typeof(SqlBetweenAttribute), false);if (attr != null){string field = attr.FieldName;}}}}public class TestModel{public int ID { get; set; }public string Name { get; set; }[SqlBetween("field", "End")]public DateTime Begin { get; set; }[SqlBetween("field", "Begin", false)]public DateTime End { get; set; }}
}
使用特性
/// <summary>/// 从实体中获取属性值不为空的属性和值,用于数据库Select的Where条件/// 暂时只支持,int、string、double、DateTime/// 要求数值类型默认为-1/// </summary>/// <param name="data"></param>/// <param name="prefix">前缀</param>/// <returns></returns>public static List<string> GetPropertyValueNotNullForSelectWhere(this object data, string prefix){string item = "";List<string> items = new List<string>();Dictionary<string, SqlBetweenAttribute> dic = new Dictionary<string, SqlBetweenAttribute>();DateTime dateTime = new DateTime(1, 1, 1, 0, 0, 0);PropertyInfo[] propertyInfos = data.GetType().GetProperties();foreach (PropertyInfo propertyInfo in propertyInfos){if (propertyInfo.Name.ToUpper() == "ID")continue;item = "";object obj = propertyInfo.GetValue(data, null);switch (propertyInfo.PropertyType.FullName){case "System.Int32":if (Convert.ToInt32(obj) == -1)continue;item = $" and {prefix}{propertyInfo.Name}={Convert.ToInt32(obj)}";break;case "System.String":if (Convert.ToString(obj) == "")continue;item = $" and {prefix}{propertyInfo.Name}='{Convert.ToString(obj)}'";break;case "System.Double":if (Convert.ToDouble(obj) == -1)continue;item = $" and {prefix}{propertyInfo.Name}={Convert.ToDouble(obj)}";break;case "System.Decimal":if (Convert.ToDecimal(obj) == -1)continue;item = $" and {prefix}{propertyInfo.Name}={Convert.ToDecimal(obj)}";break;case "System.DateTime":obj = propertyInfo.GetValue(data, null);if (Convert.ToDateTime(obj) == dateTime)continue;item = $" and {prefix}{propertyInfo.Name}='{Convert.ToDateTime(obj)}'";break;}//if(!CheckAttrSqlBetween(propertyInfo, obj, ref dic, ref item))// continue;CheckAttrSqlRange(propertyInfo, obj, ref item, prefix);CheckAttrSqlLike(propertyInfo, obj, ref item, prefix);if (!CheckAttrSqlIgnore(propertyInfo, obj, ref item))continue;items.Add(item);}return items;}/// <summary>/// 检查属性是否被SqlBetween特性修饰,并处理/// </summary>/// <param name="propertyInfo">实体的属性对象</param>/// <param name="obj">属性的值</param>/// <param name="dic">暂存特性的字典</param>/// <param name="item"></param>/// <returns>true 表示需要把item加到List<string>中</returns>static bool CheckAttrSqlBetween(PropertyInfo propertyInfo, object obj, ref Dictionary<string, SqlBetweenAttribute> dic, ref string item){SqlBetweenAttribute attr = (SqlBetweenAttribute)propertyInfo.GetCustomAttribute(typeof(SqlBetweenAttribute), false);if (attr == null)return true;attr.Value = obj;if (!dic.ContainsKey(attr.AnotherFieldName)){ //缺少另外一个,先缓存dic.Add(attr.AnotherFieldName, attr);return false;}else{SqlBetweenAttribute _attr = dic[attr.AnotherFieldName];dic.Remove(attr.AnotherFieldName);SqlBetweenAttribute attrb = attr.IsStart ? attr : _attr;SqlBetweenAttribute attre = attr.IsStart ? _attr : attr;switch (propertyInfo.PropertyType.FullName){case "System.Int32":case "System.Double":case "System.Decimal":item = $" and {attr.FieldName} between {attrb.Value} and {attre.Value}";break;case "System.String":case "System.DateTime":item = $" and {attr.FieldName} between '{attrb.Value}' and '{attre.Value}'";break;}return true;}}/// <summary>/// 检查属性是否被SqlRange特性修饰,并处理/// </summary>/// <param name="propertyInfo"></param>/// <param name="obj"></param>/// <param name="item"></param>/// <returns></returns>static void CheckAttrSqlRange(PropertyInfo propertyInfo, object obj, ref string item, string prefix){SqlRangeAttribute attr = (SqlRangeAttribute)propertyInfo.GetCustomAttribute(typeof(SqlRangeAttribute), false);if (attr == null)return;switch (propertyInfo.PropertyType.FullName){case "System.Int32":case "System.Double":case "System.Decimal":item = $" and {prefix}{attr.FieldName} {attr.Range} {obj} ";break;case "System.String":case "System.DateTime":item = $" and {prefix}{attr.FieldName} {attr.Range} '{obj}' ";break;}return;}/// <summary>/// 检查属性是否被SqlLike特性修饰,并处理/// </summary>/// <param name="propertyInfo"></param>/// <param name="obj"></param>/// <param name="item"></param>static void CheckAttrSqlLike(PropertyInfo propertyInfo, object obj, ref string item, string prefix){SqlLikeAttribute attr = (SqlLikeAttribute)propertyInfo.GetCustomAttribute(typeof(SqlLikeAttribute), false);if (attr == null)return;switch (propertyInfo.PropertyType.FullName){case "System.String":item = $" and ({prefix}{attr.FieldName} like '%{obj}%' or {prefix}{attr.FieldName}='{obj}') ";break;}return;}/// <summary>/// 检查属性是否被SqlIgnoreAttribute特性修饰,如果修饰则不加入到Where条件中/// </summary>/// <param name="propertyInfo"></param>/// <param name="obj"></param>/// <param name="item"></param>/// <returns></returns>static bool CheckAttrSqlIgnore(PropertyInfo propertyInfo, object obj, ref string item){SqlIgnoreAttribute attr = (SqlIgnoreAttribute)propertyInfo.GetCustomAttribute(typeof(SqlIgnoreAttribute), false);if (attr == null)return true;elsereturn false;}
相关文章:
C#自定义特性-SQL
语法 原则 自定义特性必须继承自System.Attribute类; AttributeUsage属性来指定特性的使用范围和是否允许重复等; 在特性类中定义属性,这些属性将用于存储特性值。 示例 using System;// 定义一个自定义特性类 [Attribute…...
协方差矩阵及其计算方法
协方差矩阵(Covariance Matrix)是一个描述多维数据特征之间相互关系的矩阵,广泛应用于统计学和机器学习中。它用于表示各个特征之间的协方差,是分析多维数据分布和特征依赖性的重要工具。 什么是协方差矩阵? 协方差矩…...
【OH】openHarmony开发环境搭建(基于windows子系统WSL)
前言 本文主要介绍基于windows子系统WSL搭建openHarmony开发环境。 WSL与Vmware虚拟机的区别,可以查看WSL与虚拟机的区别 更详细的安装配置过程可参考微软官网: 安装 WSL 前提 以下基于windows 111专业版进行配置,windows 10应该也是可以…...
Visual Studio Code 端口转发功能详解
Visual Studio Code 端口转发功能详解 引言 Visual Studio Code(简称 VS Code)是一个功能强大的源代码编辑器,它支持多种编程语言的语法高亮、智能代码补全、自定义快捷键、代码重构等特性。除了这些基本功能外,VS Code 还提供了…...
Android Framework AMS(14)ContentProvider分析-1(CP组件应用及开机启动注册流程解读)
该系列文章总纲链接:专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明: 说明:本章节主要解读ContentProvider组件的基本知识。关注思维导图中左上侧部分即可。 有了前面activity组件分析、service组件分析、广播组件分析的基…...
Three.js PBR材质
本文将详细介绍Three.js中的PBR(Physically Based Rendering)材质,包括PBR的基本概念、适用场景、PBR材质的构建以及一些高级应用技巧。 1. PBR(Physically Based Rendering)基本概念 PBR,即Physically B…...
智谱AI清影升级:引领AI视频进入音效新时代
前几天智谱推出了新清影,该版本支持4k、60帧超高清画质、任意尺寸,并且自带音效的10秒视频,让ai生视频告别了"哑巴时代"。 智谱AI视频腾空出世,可灵遭遇强劲挑战!究竟谁是行业翘楚?(附测评案例)之前智谱出世那时体验了一…...
嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)
引言:在我们的日常使用中,MOS就是个纯粹的电子开关,虽然MOS管也有放大作用,但是几乎用不到,只用它的开关作用,一般的电机驱动,开关电源,逆变器等大功率设备,全部使用MOS管…...
Centos 9 安装 PostgreSQL 16 并支持远程访问
仅列出核心操作,可以解决使用过程中遇到的访问问题。 1 安装 使用dnf源安装 sudo dnf module -y install postgresql:16 2 配置文件夹权限 使用root权限操作 sudo chown postgres:postgres /var/lib/pgsql/datasudo chmod -R 0750 /var/lib/pgsql/data 3 初…...
Dubbo源码解析(三)
一、Dubbo整合Spring启动流程 Dubbo的使用可以不依赖Spring,但是生产环境中Dubbo都是整合到Spring中一起使用,所以本章就解析Dubbo整合Spring的启动流程 一、传统的xml解析方式 一、Dubbo配置解析流程 在Java 中,一切皆对象。在JDK 中使用…...
HarmonyOS Next星河版笔记--界面开发(5)
1.字符串 1.1.字符串拼接 作用:把两个或多个字符串,拼成一个字符串。(通常是用来拼接字符串和变量) hello world > helloworld 加好作用:拼接 let name:string 小明 console.log(简介信息,名字是 name) …...
Spring Boot3 实战案例合集上线了
Spring Boot3实战案例合集...
在Ubuntu 24.04 LTS上安装飞桨PaddleX
前面我们介绍了《在Windows用远程桌面访问Ubuntu 24.04.1 LTS》本文接着介绍安装飞桨PaddleX。 PaddleX 3.0 是基于飞桨框架构建的一站式全流程开发工具,它集成了众多开箱即用的预训练模型,可以实现模型从训练到推理的全流程开发,支持国内外多…...
Homebrew 命令大全
Homebrew 是 macOS 和 Linux 系统上的一个流行的包管理器,它可以帮助用户轻松地安装、更新和管理软件包。以下是一些常用的 Homebrew 命令: 安装 Homebrew 如果你还没有安装 Homebrew,可以使用以下命令在 macOS 上进行安装: /b…...
Docker+Django项目部署-从Linux+Windows实战
一、概述 1. 什么是Docker Docker 是一个开源的应用容器引擎,支持在win、mac、Linux系统上进行安装。可以帮助我们在一台电脑上创建出多个隔离的环境,比传统的虚拟机极大的节省资源 。 为什么要创建隔离的环境? 假设你先在有一个centos7.…...
前端 JS 实用操作总结
目录 1、重构解构 1、数组解构 2、对象解构 3、...展开 2、箭头函数 1、简写 2、this指向 3、没有arguments 4、普通函数this的指向 3、数组实用方法 1、map和filter 2、find 3、reduce 1、重构解构 1、数组解构 const arr ["唐僧", "孙悟空&quo…...
11.15 机器学习-集成学习方法-随机森林
# 机器学习中有一种大类叫**集成学习**(Ensemble Learning),集成学习的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话: # 三个臭皮匠,…...
【SQL】E-R模型(实体-联系模型)
目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型(E-R数据模型)被开发来方便数据库的设计,它是通过允许定义代表数据库全局逻辑结构的企业模式…...
C/C++静态库引用过程中出现符号未定义的处理方式
问题背景: 在接入新库(静态库)时遇到了符号未定义问题,并发现改变静态库的链接顺序可以解决问题。 问题根源: 静态库是由 .o 文件拼接而成的,链接静态库时,链接器以 .o 文件为单位进行处理。链接…...
『VUE』27. 透传属性与inheritAttrs(详细图文注释)
目录 什么是透传属性(Forwarding Attributes)使用条件唯一根节点禁用透传属性继承总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 什么是透传属性(Forwarding Attributes) 在 V…...
Python爬虫实战:手把手教你如何采集开源许可证 FAQ 文章归档!
㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐⭐ (中级) 🉐福利: 一次订阅后,专栏内的所有文章…...
Arm CoreSight SoC-400时间戳系统架构与实现
1. Arm CoreSight SoC-400时间戳系统架构解析在复杂的多核SoC调试场景中,精确的时间戳记录能力是定位问题的关键。Arm CoreSight SoC-400采用的分层时间戳架构,通过硬件级实现解决了传统软件时间戳存在的精度不足和CPU负载问题。这套系统主要由三个核心组…...
OpenClaw Windows11 保姆级安装部署教程(专属优化、一次成功)
OpenClaw Windows11 保姆级安装部署教程(专属优化、一次成功)一、前言OpenClaw(圈内俗称「小龙虾」)是 GitHub 星标 28W 的开源本地 AI 智能体,主打全自动电脑操控能力,支持自动操作电脑、整理文件、浏览器…...
AwesomeQRCode源码阅读笔记:深入理解二维码渲染核心技术
AwesomeQRCode源码阅读笔记:深入理解二维码渲染核心技术 【免费下载链接】AwesomeQRCode An awesome QR code generator for Android. 项目地址: https://gitcode.com/gh_mirrors/aw/AwesomeQRCode 想要为你的Android应用添加炫酷的二维码生成功能吗…...
别再用Excel硬扛了!SPSS数据视图和变量视图保姆级上手指南
别再用Excel硬扛了!SPSS数据视图和变量视图保姆级上手指南 第一次打开SPSS时,很多从Excel转过来的用户会愣住——这个界面怎么既熟悉又陌生?左边明明也是表格,但为什么右键菜单里找不到"设置单元格格式"?右上…...
基于PSCAD的光伏-火电打捆直流送出系统建模与扰动特性仿真研究
基于PSCAD的光伏-火电打捆直流送出系统建模与扰动特性仿真研究 摘要 随着我国“双碳”目标的深入推进,以光伏为代表的新能源发电装机规模持续快速增长。然而,光伏发电具有间歇性和波动性特征,大规模并网对电力系统的安全稳定运行提出了严峻挑战。将光伏与火电打捆经高压直…...
下载 | Win11 官方精简版,系统占用空间极少!(4月末更新、Win11 IoT物联网 LTSC版、适合老电脑安装使用)
⏩ 【资源A023】Win11 LTSC 2024 ISO系统映像 🔶Win11 物联网IoT LTSC版,默认无TPM等硬件限制,更方便老电脑安装使用。LTSC是长期服务渠道版本,网友俗称“老坛酸菜版”,相当于微软官方的精简版Win11,精简了…...
输入流避坑全指南:从 Read() 编码溢出到 ReadLine() 缓冲区残留
1. 灵异事件:为什么我的循环跑了 52 次? 在编写基础逻辑题时,我曾遇到一个极其诡异的Bug:要求用户输入边长nnn打印正方形,我输入4,结果程序打印了 52行符号。 问题代码: int n Console.Read();…...
从LTV-M501到系统集成:高速光耦隔离通信的选型与实战设计
1. 高速光耦隔离通信的核心价值 第一次接触工业现场总线改造项目时,我被电机控制器和PLC之间的通信干扰问题折磨了整整两周。直到老工程师递给我几个LTV-M501光耦,问题才迎刃而解。这种通过光信号传递电信号的器件,就像给通信线路装上了"…...
【信息科学与工程学】【物理/化学科学和工程技术】知识体系018 第十八篇 界面科学01 界面物理
界面科学知识体系分级分类列表 概述 界面科学是研究两相之间界面(表面)现象、性质、过程和规律的交叉学科。本列表系统整理了界面科学领域的核心概念、理论、技术和应用,涵盖从基础理论到前沿应用的完整知识体系。 界面科学知识体系分类表格...
