• 利用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操作的性能优化方式》

  • 相关阅读:
    一个IBM人的离职泪:伟大公司 SB老板 苦逼员工
    分享:cmake for protobuff
    鸽巢原理
    分享:ADT在线安装(http://dlssl.google.com/android/eclips...
    科学家将蝌蚪眼睛植入其尾部 并具有正常视力
    Artificial Intelligence: How To Build A Robot Udacity
    http://ndevilla.free.fr/
    发现几个计算广告学的课程
    base64_百度百科
    分享:查询日志过去一分钟的并发python
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/2340935.html
Copyright © 2020-2023  润新知