千家信息网

C#抽象增删改怎么实现

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,本篇内容主要讲解"C#抽象增删改怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C#抽象增删改怎么实现"吧!现在业界火了一种ORM 框架,那就是Da
千家信息网最后更新 2025年02月03日C#抽象增删改怎么实现

本篇内容主要讲解"C#抽象增删改怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C#抽象增删改怎么实现"吧!

现在业界火了一种ORM 框架,那就是Dapper,我也是Dapper的粉丝之一,而我总结出来的框架也是基于Daaper。下面是我的代码,首先是Dapper Helper类,数据库通用访问类(用Nuget工具先把Dapper类引用到NetUtility.Dapper.Core项目中去):

NetUtility.Dapper.Core.DataBaseAccess.cs

  1. using System;

  2. using System.Collections.Generic;

  3. using System.Configuration;

  4. using System.Data.SqlClient;

  5. using System.Linq;

  6. using System.Text;

  7. using System.Threading.Tasks;

  8. using Dapper;

  9. using System.Data;

  10. using NetUtility.Entity;

  11. using System.Reflection;

  12. namespace NetUtility.Dapper.Core

  13. {

  14. ///

  15. /// 数据库访问类

  16. ///

  17. public class DataBaseAccess

  18. {

  19. public static SqlConnection CreateConnection()

  20. {

  21. string connStr = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;

  22. SqlConnection conn = new SqlConnection(connStr);

  23. conn.Open();

  24. return conn;

  25. }

  26. ///

  27. /// 执行增、删、改方法

  28. ///

  29. ///

  30. ///

  31. ///

  32. public static int Execute(string sql, object parms = null)

  33. {

  34. using (IDbConnection conn = CreateConnection())

  35. {

  36. return conn.Execute(sql,parms);

  37. }

  38. }

  39. ///

  40. /// 得到单行单列

  41. ///

  42. ///

  43. ///

  44. ///

  45. public static object ExecuteScalar(string sql, object parms = null)

  46. {

  47. using (IDbConnection conn = CreateConnection())

  48. {

  49. return conn.ExecuteScalar(sql, parms);

  50. }

  51. }

  52. ///

  53. /// 单个数据集查询

  54. ///

  55. ///

  56. ///

  57. ///

  58. public static List Query(string sql,Func pre ,object parms = null)

  59. {

  60. using (IDbConnection conn = CreateConnection())

  61. {

  62. return conn.Query(sql, parms).Where(pre).ToList();

  63. }

  64. }

  65. ///

  66. /// 单个数据集查询

  67. ///

  68. ///

  69. ///

  70. ///

  71. public static List Query(string sql, object parms = null)

  72. {

  73. using (IDbConnection conn = CreateConnection())

  74. {

  75. return conn.Query(sql, parms).ToList();

  76. }

  77. }

  78. ///

  79. /// 多个数据集查询

  80. ///

  81. ///

  82. ///

  83. ///

  84. public static SqlMapper.GridReader MultyQuery(string sql, object parms = null)

  85. {

  86. using (IDbConnection conn = CreateConnection())

  87. {

  88. return conn.QueryMultiple(sql, parms);

  89. }

  90. }

  91. ///

  92. /// 单个数据集查询

  93. ///

  94. ///

  95. ///

  96. ///

  97. public static TEntity FirstOrDefault(string sql,Func selector, object parms = null)

  98. {

  99. using (IDbConnection conn = CreateConnection())

  100. {

  101. return conn.Query(sql, parms).Where(selector).FirstOrDefault();

  102. }

  103. }

  104. }

  105. }

我把增删改查抽象出来了,少不了的就是SQL语句的生成,生成SQL语句,要么是映射,要么是反射,而我用的是反射,给一个Entity类,我读取他所有属性和字段,然后生成对应的SQL语句。 NetUtility.Dapper.Core.DataMapping.cs

using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks;  namespace NetUtility.Dapper.Core {     internal class DataMapping where TModel : class     {         #region 数据库类型+DataBaseType         ///          /// 数据库类型         ///          public static string DataBaseType         {             get             {                 string strType = ConfigurationManager.AppSettings["DataBaseType"];                 if (!string.IsNullOrEmpty(strType))                 {                     return strType;                 }                 else                 {                     return string.Empty;                 }             }         }          #endregion          #region 主键属性字段+PrimaryKey         ///          /// 主键字段名称         ///          public static string PrimaryKey         {             get             {                 Type t = typeof(TModel);                 TableInfoAttribute tableInfo = t.GetCustomAttribute(typeof(TableInfoAttribute), true) as TableInfoAttribute;                    if (tableInfo!=null)//如果没有标识表信息特性,则通过表名向数据库中得到主键信息                 {                     return tableInfo.PrimaryKey;                               }                 else                 {                     string tableName = TableName();                     return DataBaseAccess.ExecuteScalar("SELECT name FROM SysColumns WHERE id=Object_Id('" + tableName + "') and colid=(select top 1 colid from sysindexkeys where id=Object_Id('" + tableName + "'))").ToString();                 }             }         }          #endregion          #region 获取表名+TableName         ///          /// 获取表名         ///          /// 数据库表名前缀         ///          public static string TableName(string prev = "")         {             Type t = typeof(TModel);             TableInfoAttribute tableInfo = t.GetCustomAttribute(typeof(TableInfoAttribute), true) as TableInfoAttribute;             return tableInfo != null ? tableInfo.TableName : string.Concat(prev, t.Name);         }          #endregion          #region Select 查询语句+GetQuerySql         ///          /// Select 查询语句         ///          ///          public static string GetQuerySql()         {             StringBuilder sql = new StringBuilder("select * from ");             sql.Append(TableName());              return sql.ToString();         }          #endregion          #region Insert非Null属性的对象实例 Sql 语句+GetInsertSql         ///          /// Insert 非Null属性的对象实例 Sql 语句         ///          ///          ///          public static string GetInsertSql(TModel model)         {             StringBuilder sql = new StringBuilder("insert into ");              string[] props = Propertys(model);             sql.Append(TableName());             sql.Append("(");             sql.Append(string.Join(",", props));             sql.Append(") values(@");             sql.Append(string.Join(",@", props));             sql.Append(");select @@IDENTITY");              return sql.ToString();         }          #endregion          #region Delete Sql 语句+GetDeleteSql         ///          /// Delete Sql 语句         ///          ///          public static string GetDeleteSql()         {             return string.Format(@"delete from {0} where {1} in @IdList", TableName(), PrimaryKey);         }          #endregion          #region Update 非Null属性的对象实例 Sql语句+GetUpdateSql         ///          /// Update 非Null属性的对象实例 Sql语句         ///          ///          ///          public static string GetUpdateSql(TModel model)         {             StringBuilder sql = new StringBuilder("update ");             string[] props = Propertys(model);             sql.Append(TableName());             sql.Append(" set ");             foreach (string propName in props)             {                 sql.Append(propName + "=@" + propName + ",");             }             sql.Remove(sql.Length - 1, 1);             sql.Append(" where " + PrimaryKey + "=@Id");             return sql.ToString();         }          #endregion          #region 非主键且非Null属性集合+Propertys         ///          /// 非主键且非Null属性         ///          ///          ///          public static string[] Propertys(TModel model)         {             PropertyInfo[] props = typeof(TModel).GetProperties();             List list = new List();             string key = PrimaryKey;             if (props != null && props.Length > 0)             {                 foreach (PropertyInfo prop in props)                 {                     if (prop.GetValue(model, null) != null && !prop.Name.Equals(key, StringComparison.OrdinalIgnoreCase))                     {                         list.Add(prop.Name);                     }                 }             }              return list.ToArray();         }          #endregion     } }

代码中的TableInfoAttribute 类是我建一个属性特性类,用于标识表名和主键名称的特性类,假如Entity实体类上面没有标识主键名称,框架默认会用Entity类名作为表名,建议***标识一下表名和主键名称。

NetUtility.Dapper.Core.TableInfoAttribute.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace NetUtility.Dapper.Core {     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]     ///      /// 标识表名、主键等信息特性类     ///      public class TableInfoAttribute : Attribute     {         ///          /// 数据库表名         ///          public string TableName { get; set; }          ///          /// 主键名称         ///          public string PrimaryKey { get; set; }          public TableInfoAttribute()         { }         public TableInfoAttribute(string tableName, string key)         {             this.TableName = tableName;             this.PrimaryKey = key;         }     } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace NetUtility.Dapper.Core {     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]     ///      /// 标识表名、主键等信息特性类     ///      public class TableInfoAttribute : Attribute     {         ///          /// 数据库表名         ///          public string TableName { get; set; }          ///          /// 主键名称         ///          public string PrimaryKey { get; set; }          public TableInfoAttribute()         { }         public TableInfoAttribute(string tableName, string key)         {             this.TableName = tableName;             this.PrimaryKey = key;         }     } }

好,下面就是新建一个抽象类,用于抽象出增删改查的 ExecuteSql 泛型抽象类

NetUtility.Dapper.Core.ExecuteSql.cs

using Dapper; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace NetUtility.Dapper.Core {     public abstract class ExecuteSql where TModel : class     {         #region Insert非Null属性的对象实例+Insert(TModel model)         ///          /// Insert非Null属性的对象实例         ///          ///          ///          public virtual int Insert(TModel model)         {             string sql = DataMapping.GetInsertSql(model);             object res = DataBaseAccess.ExecuteScalar(sql, model);             if (res != null)             {                 return Convert.ToInt32(res);             }             return 0;         }          #endregion          #region Select * 查询+Query()         ///          /// Select * 查询         ///              ///          public virtual List Query()         {             string sql = DataMapping.GetQuerySql();             return DataBaseAccess.Query(sql);         }          #endregion          #region 带查询条件的Select查询+Query(Func selector)         ///          /// 带查询条件的Select查询         ///          ///          ///          public virtual List Query(Func selector)         {             string sql = DataMapping.GetQuerySql();             return DataBaseAccess.Query(sql, selector);         }          #endregion          #region  得到一个对象的实例+FirstOrDefault(Func selector = null)         ///          /// 得到一个对象的实例         ///          ///          ///          public virtual TModel FirstOrDefault(Func selector = null)         {             string sql = DataMapping.GetQuerySql();             return DataBaseAccess.FirstOrDefault(sql, selector);         }          #endregion          #region 批量删除+Delete(string[] IdList)         ///          /// 批量删除         ///          ///          ///          public virtual int Delete(string[] IdList)         {             return DataBaseAccess.Execute(DataMapping.GetDeleteSql(), new { IdList = IdList });         }          #endregion          #region Update 一个非Null属性的对象+Update(TModel model)         ///          /// Update 一个非Null属性的对象         ///          ///          ///          public virtual int Update(TModel model)         {             return DataBaseAccess.Execute(DataMapping.GetUpdateSql(model), model);         }          #endregion          #region 获取多个数据集+MultyQuery(string sql, object param = null)         ///          /// 获取多个数据集         ///          ///          ///          ///          public virtual SqlMapper.GridReader MultyQuery(string sql, object param = null)         {             return DataBaseAccess.MultyQuery(sql, param);         }          #endregion              } }

ExecuteSql.cs 类中的方法全是 virsual方法,使用者可以重写他,特别是查询方法,一定会被重写掉。现在NetUtility.Dapper.Core项目中的类全部写完了,现在 是我业务类的引用了,我现在只需要建一个业务类继承这个抽象类,这些增删改查方法全都有了,已经不需要写了!

下面是我的两个实体类,实体类用TableInfoAttribute特性类标识出了主键名称和表名称:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NetUtility.Dapper.Core;  namespace NetUtility.Entity {     [TableInfo(PrimaryKey ="Id",TableName ="Classes")]     public class Classes     {   public int Id { get; set; }         public string Name { get; set; }         public string Code { get; set; }     } }  using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NetUtility.Dapper.Core;  namespace NetUtility.Entity {     [TableInfo(PrimaryKey = "Id", TableName = "Student")]     public class Student     {                public int Id { get; set; }         public string Name { get; set; }         public string Code { get; set; }         public int? Age { get; set; }         public DateTime? JoinDate { get; set; }         public int? ClassesId { get; set; }     } }

我再新建一个StudentRepertories业务类,继承ExecuteSql抽象类。

NetUtility.Repertories.StudentRepertories.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NetUtility.Dapper.Core; using NetUtility.Entity; using NetUtility.Entity.ExstendEntity;//这个是实体类的扩展类,项目中如不需要可移除 using System.Data; using Dapper;  namespace NetUtility.Repertories {     public class StudentRepertories : ExecuteSql     {          public override List Query()         {             return base.Query();         }          public  List QueryInfo()         {             string sql = "select * from Student a left join Classes b on a.ClassesId=b.Id";              using (IDbConnection conn = DataBaseAccess.CreateConnection())             {                 return conn.Query(sql, (stu, classes) => { stu.ClassesModel = classes; return stu; }).ToList();                }         }     } }

好了,现在我们只需要建一个控制台测试一下有没有问题就是了,亲测,木有问题。

NetUtility.ConsoleItem

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NetUtility.Repertories; using NetUtility.Entity;  namespace NetUtility.ConsoleItem {     class Program     {         static void Main(string[] args)         {             //业务对象              StudentRepertories stu = new StudentRepertories();             //实体对象             var model = new Student(){Age = 100,ClassesId = 1,Code = "3200020021",JoinDate = DateTime.Now,Name = "老徐"};                    //新增一个对象             int StudentId = stu.Insert(model);             var newModel = stu.FirstOrDefault(a => a.Id == StudentId);              //Lambda表达式查询             var list = stu.Query(a => a.Age == 100);             //不带参数查询             var studentInfoList = stu.QueryInfo();              #region 更新             newModel.Code = "1111111111";             newModel.Id = StudentId;             stu.Update(newModel);             #endregion           // 删除             stu.Delete(new string[] { newModel.Id.ToString() });                      Console.ReadKey();         }     } }

到此,相信大家对"C#抽象增删改怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0