突破传统! Attribute简化SQL删除操作

简介:

昨天跟朋友聊天,发现他们的项目数据层使用的是最基础的纯SQL语句+SqlParameter进行数据交互的,大家知道SELECT、UPDATE、CREATE对于表的依赖性比较大,然后删除语句却不一样,它的语法比较简单,大致有以下几种:

  1、DELETE FROM TableName

  2、DELETE FROM TableName WHERE ID = idValue

  3、DELETE FROM TableName WHERE ID IN (id1, id2, id3, id4....)

  于是我们要实现这个简单的功能来简化比较常用的删除就比较容易了,主要保留2个数据,1个是TableName,另外1个就是ID了,如果实体类有基类的情况下,我们可以扩展基类,提供2个接口,让其他的实体类去实现来保存对应的TableName和ID。但是如果没有基类的话,我们也可以利用Attribute来实现这个功能。

  Attribute代码如下:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class DbAttribute : Attribute
{
     #region 变量

     private string m_TableName = null;

     private string m_PrimaryKey = null;

     #endregion

     #region 构造函数

     public DbAttribute(string tableName, string primaryKey)
     {
         this.m_TableName = tableName;
         this.m_PrimaryKey = primaryKey;
     }

     #endregion

     #region 普通方法

     public string GetDeleteAllSQL()
     {
         return string.Format(@"
             DELETE
             FROM
                 {0}", this.m_TableName);
     }

     /// <summary>
     /// 获取根据主键删除表数据
     /// </summary>
     /// <typeparam name="TParam">数据库类型</typeparam>
     /// <typeparam name="TPKValue">主键类型名</typeparam>
     /// <param name="tPKValue">主键值</param>
     /// <returns></returns>
     public KeyValuePair<string, TParam[]> GetDeleteByPrimaryKeySQL<TParam, TPKValue>(TPKValue tPKValue)
         where TParam : DbParameter, new()
     {
         var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
             WHERE
                 {0} = :_pk_", this.m_PrimaryKey));
         MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
         var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
         {
             {"_pk_", tPKValue}
         });
         return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
     }

     /// <summary>
     /// 获取根据主键数组删除表数据
     /// </summary>
     /// <typeparam name="TParam"></typeparam>
     /// <typeparam name="TPKValue"></typeparam>
     /// <param name="arrTPKValue"></param>
     /// <returns></returns>
     public KeyValuePair<string, TParam[]> GetDeleteInPrimaryKeySQL<TParam, TPKValue>(params TPKValue[] arrTPKValue)
         where TParam : DbParameter, new()
     {
         var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
             WHERE
                 {0} IN (:_arr_pk_)", this.m_PrimaryKey));
         MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
         var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
         {
             {"_arr_pk_", arrTPKValue}
         });
         return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
     }

     #endregion
}
以上用到泛型模式以及前几篇文章提到的替换参数的方法,文章在此。有了以上的Attribute,我们就可以用它来标记实体类了,代码如下:

[Db("Permission_Info", "p_id")]
public partial class Permission
{
     //属性、方法等
}
为了演示,我写了一个用来调用的方法,来测试产生的语句和参数。测试类代码如下:

public class DbOperate
{
     public static string GetDeleteSQL<TClass>() where TClass : new()
     {
         var attr = GetAttribute<TClass>();
         var sql = string.Empty;
         if (null != attr)
         {
             sql = attr.GetDeleteAllSQL();
         }
         return sql;
     }

     public static KeyValuePair<string, SqlParameter[]> GetDeleteByIdSQL<TClass, TPKValUe>(params TPKValUe[] arrTPKValue) where TClass : new()
     {
         var attr = GetAttribute<TClass>();
         KeyValuePair<string, SqlParameter[]> pair = new KeyValuePair<string, SqlParameter[]>(null, null);
         if (null != attr)
         {
             if (1 == arrTPKValue.Length)
             {
                 pair = attr.GetDeleteByPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue[0]);
             }
             else
             {
                 pair = attr.GetDeleteInPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue);
             }
         }
         return pair;
     }

     static DbAttribute GetAttribute<T>() where T : new()
     {
         var arrAttribute = typeof(T).GetCustomAttributes(typeof(DbAttribute), false);
         DbAttribute attr = null;
         if (0 < arrAttribute.Length)
         {
             attr = arrAttribute[0] as DbAttribute;
         }
         return attr;
     }
}
代码测试如下:

利用Attribute简化SQL删除操作

利用Attribute简化SQL删除操作

利用Attribute简化SQL删除操作

 

  以上代码并不是最优的选择,我们仍然可以在Attribute调用的地方进行优化,大家可以参考老赵的《Attribute操作的性能优化方式》










本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/778416,如需转载请自行联系原作者
目录
相关文章
|
SQL 存储 关系型数据库
【MySQL系列】SQL语句入门(创建删除操作)、字符集和数据类型详解
哈喽,大家好💓,在上一篇博客中,大致讲解了数据库的相关知识,它的作用、定义、分类等等。从本篇博客开始,将详细讲解关系型数据库MySQL的操作与使用,以及SQL语句的讲解。
|
SQL 数据库 C语言
使用SQL语句实现数据插入、修改和删除操作
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句实现数据插入、修改和删除操作。
|
SQL
关于sql中的更新和删除操作的重要性
昨天update的时候没有加where条件 导致数据库里面的全部数据更新 这个操作 真是不应该  罪过啊 罪过啊   凡是写关于更新或者删除的语句 记得一定要加条件 不然的话 会导致全局数据变化  致命性的操作啊 限制在指定条件范围内 还有字段选择 尽量选择 唯一性的字段 也就是说...
578 0
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
135 13
|
5月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
5月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
73 6
|
5月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
462 1
|
5月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
381 3
|
4月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
532 0