zoukankan      html  css  js  c++  java
  • 利用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代码如下:

     1 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    2 public class DbAttribute : Attribute
    3 {
    4 #region 变量
    5
    6 private string m_TableName = null;
    7
    8 private string m_PrimaryKey = null;
    9
    10 #endregion
    11
    12 #region 构造函数
    13
    14 public DbAttribute(string tableName, string primaryKey)
    15 {
    16 this.m_TableName = tableName;
    17 this.m_PrimaryKey = primaryKey;
    18 }
    19
    20 #endregion
    21
    22 #region 普通方法
    23
    24 public string GetDeleteAllSQL()
    25 {
    26 return string.Format(@"
    27 DELETE
    28 FROM
    29 {0}", this.m_TableName);
    30 }
    31
    32 /// <summary>
    33 /// 获取根据主键删除表数据
    34 /// </summary>
    35 /// <typeparam name="TParam">数据库类型</typeparam>
    36 /// <typeparam name="TPKValue">主键类型名</typeparam>
    37 /// <param name="tPKValue">主键值</param>
    38 /// <returns></returns>
    39 public KeyValuePair<string, TParam[]> GetDeleteByPrimaryKeySQL<TParam, TPKValue>(TPKValue tPKValue)
    40 where TParam : DbParameter, new()
    41 {
    42 var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
    43 WHERE
    44 {0} = :_pk_", this.m_PrimaryKey));
    45 MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
    46 var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
    47 {
    48 {"_pk_", tPKValue}
    49 });
    50 return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
    51 }
    52
    53 /// <summary>
    54 /// 获取根据主键数组删除表数据
    55 /// </summary>
    56 /// <typeparam name="TParam"></typeparam>
    57 /// <typeparam name="TPKValue"></typeparam>
    58 /// <param name="arrTPKValue"></param>
    59 /// <returns></returns>
    60 public KeyValuePair<string, TParam[]> GetDeleteInPrimaryKeySQL<TParam, TPKValue>(params TPKValue[] arrTPKValue)
    61 where TParam : DbParameter, new()
    62 {
    63 var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
    64 WHERE
    65 {0} IN (:_arr_pk_)", this.m_PrimaryKey));
    66 MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
    67 var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
    68 {
    69 {"_arr_pk_", arrTPKValue}
    70 });
    71 return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
    72 }
    73
    74 #endregion
    75 }

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

    1 [Db("Permission_Info", "p_id")]
    2 public partial class Permission
    3 {
    4 //属性、方法等
    5 }

      为了演示,我写了一个用来调用的方法,来测试产生的语句和参数。测试类代码如下:

     1 public class DbOperate
    2 {
    3 public static string GetDeleteSQL<TClass>() where TClass : new()
    4 {
    5 var attr = GetAttribute<TClass>();
    6 var sql = string.Empty;
    7 if (null != attr)
    8 {
    9 sql = attr.GetDeleteAllSQL();
    10 }
    11 return sql;
    12 }
    13
    14 public static KeyValuePair<string, SqlParameter[]> GetDeleteByIdSQL<TClass, TPKValUe>(params TPKValUe[] arrTPKValue) where TClass : new()
    15 {
    16 var attr = GetAttribute<TClass>();
    17 KeyValuePair<string, SqlParameter[]> pair = new KeyValuePair<string, SqlParameter[]>(null, null);
    18 if (null != attr)
    19 {
    20 if (1 == arrTPKValue.Length)
    21 {
    22 pair = attr.GetDeleteByPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue[0]);
    23 }
    24 else
    25 {
    26 pair = attr.GetDeleteInPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue);
    27 }
    28 }
    29 return pair;
    30 }
    31
    32 static DbAttribute GetAttribute<T>() where T : new()
    33 {
    34 var arrAttribute = typeof(T).GetCustomAttributes(typeof(DbAttribute), false);
    35 DbAttribute attr = null;
    36 if (0 < arrAttribute.Length)
    37 {
    38 attr = arrAttribute[0] as DbAttribute;
    39 }
    40 return attr;
    41 }
    42 }

      代码测试如下:

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

  • 相关阅读:
    利用递归分割(Split)字符串
    SQL Server2012 T-SQL基础教程--读书笔记(1-4章)
    kindeditor编辑器的使用
    echarts绘制四川地图
    Windows下搭建PHP开发环境(Apache+PHP+MySQL)+调试工具Xdebug的配置
    给搜索关键字添加高亮,加以颜色区分
    SQL 生成6位随机数并MD5加密输出
    微信小程序登录 .net 后端实现
    钉钉小程序http post 请求
    浅谈Web Api配合SignalR的跨域支持
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/2340935.html
Copyright © 2011-2022 走看看