当前位置: 首页 > news >正文

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类&#xff1b; AttributeUsage属性来指定特性的使用范围和是否允许重复等&#xff1b; 在特性类中定义属性&#xff0c;这些属性将用于存储特性值。 示例 using System;// 定义一个自定义特性类 [Attribute…...

协方差矩阵及其计算方法

协方差矩阵&#xff08;Covariance Matrix&#xff09;是一个描述多维数据特征之间相互关系的矩阵&#xff0c;广泛应用于统计学和机器学习中。它用于表示各个特征之间的协方差&#xff0c;是分析多维数据分布和特征依赖性的重要工具。 什么是协方差矩阵&#xff1f; 协方差矩…...

【OH】openHarmony开发环境搭建(基于windows子系统WSL)

前言 本文主要介绍基于windows子系统WSL搭建openHarmony开发环境。 WSL与Vmware虚拟机的区别&#xff0c;可以查看WSL与虚拟机的区别 更详细的安装配置过程可参考微软官网&#xff1a; ​安装 WSL 前提 以下基于windows 111专业版进行配置&#xff0c;windows 10应该也是可以…...

Visual Studio Code 端口转发功能详解

Visual Studio Code 端口转发功能详解 引言 Visual Studio Code&#xff08;简称 VS Code&#xff09;是一个功能强大的源代码编辑器&#xff0c;它支持多种编程语言的语法高亮、智能代码补全、自定义快捷键、代码重构等特性。除了这些基本功能外&#xff0c;VS Code 还提供了…...

Android Framework AMS(14)ContentProvider分析-1(CP组件应用及开机启动注册流程解读)

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读ContentProvider组件的基本知识。关注思维导图中左上侧部分即可。 有了前面activity组件分析、service组件分析、广播组件分析的基…...

Three.js PBR材质

本文将详细介绍Three.js中的PBR&#xff08;Physically Based Rendering&#xff09;材质&#xff0c;包括PBR的基本概念、适用场景、PBR材质的构建以及一些高级应用技巧。 1. PBR&#xff08;Physically Based Rendering&#xff09;基本概念 PBR&#xff0c;即Physically B…...

智谱AI清影升级:引领AI视频进入音效新时代

前几天智谱推出了新清影,该版本支持4k、60帧超高清画质、任意尺寸&#xff0c;并且自带音效的10秒视频,让ai生视频告别了"哑巴时代"。 智谱AI视频腾空出世&#xff0c;可灵遭遇强劲挑战&#xff01;究竟谁是行业翘楚&#xff1f;(附测评案例)之前智谱出世那时体验了一…...

嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)

引言&#xff1a;在我们的日常使用中&#xff0c;MOS就是个纯粹的电子开关&#xff0c;虽然MOS管也有放大作用&#xff0c;但是几乎用不到&#xff0c;只用它的开关作用&#xff0c;一般的电机驱动&#xff0c;开关电源&#xff0c;逆变器等大功率设备&#xff0c;全部使用MOS管…...

Centos 9 安装 PostgreSQL 16 并支持远程访问

仅列出核心操作&#xff0c;可以解决使用过程中遇到的访问问题。 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&#xff0c;但是生产环境中Dubbo都是整合到Spring中一起使用&#xff0c;所以本章就解析Dubbo整合Spring的启动流程 一、传统的xml解析方式 一、Dubbo配置解析流程 在Java 中&#xff0c;一切皆对象。在JDK 中使用…...

HarmonyOS Next星河版笔记--界面开发(5)

1.字符串 1.1.字符串拼接 作用&#xff1a;把两个或多个字符串&#xff0c;拼成一个字符串。&#xff08;通常是用来拼接字符串和变量&#xff09; hello world > helloworld 加好作用&#xff1a;拼接 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 是基于飞桨框架构建的一站式全流程开发工具&#xff0c;它集成了众多开箱即用的预训练模型&#xff0c;可以实现模型从训练到推理的全流程开发&#xff0c;支持国内外多…...

Homebrew 命令大全

Homebrew 是 macOS 和 Linux 系统上的一个流行的包管理器&#xff0c;它可以帮助用户轻松地安装、更新和管理软件包。以下是一些常用的 Homebrew 命令&#xff1a; 安装 Homebrew 如果你还没有安装 Homebrew&#xff0c;可以使用以下命令在 macOS 上进行安装&#xff1a; /b…...

Docker+Django项目部署-从Linux+Windows实战

一、概述 1. 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;支持在win、mac、Linux系统上进行安装。可以帮助我们在一台电脑上创建出多个隔离的环境&#xff0c;比传统的虚拟机极大的节省资源 。 为什么要创建隔离的环境&#xff1f; 假设你先在有一个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 机器学习-集成学习方法-随机森林

# 机器学习中有一种大类叫**集成学习**&#xff08;Ensemble Learning&#xff09;&#xff0c;集成学习的基本思想就是将多个分类器组合&#xff0c;从而实现一个预测效果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话&#xff1a; # 三个臭皮匠&#xff0c…...

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型&#xff08;E-R数据模型&#xff09;被开发来方便数据库的设计&#xff0c;它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…...

C/C++静态库引用过程中出现符号未定义的处理方式

问题背景&#xff1a; 在接入新库&#xff08;静态库&#xff09;时遇到了符号未定义问题&#xff0c;并发现改变静态库的链接顺序可以解决问题。 问题根源&#xff1a; 静态库是由 .o 文件拼接而成的&#xff0c;链接静态库时&#xff0c;链接器以 .o 文件为单位进行处理。链接…...

『VUE』27. 透传属性与inheritAttrs(详细图文注释)

目录 什么是透传属性&#xff08;Forwarding Attributes&#xff09;使用条件唯一根节点禁用透传属性继承总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 什么是透传属性&#xff08;Forwarding Attributes&#xff09; 在 V…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...