让C#开发更简单,抽象增删改

作者:   出处:互联网   2015-06-18 15:42:24   阅读:3

相信经常做一些MS,CRM 项目的童鞋非常有体会,大部分时间都是在复制和粘贴,大部分项目框架都是建一个三层,首先是DAL建一些增删改查,然后呢是BLL业务层再建一些增删改 查,然后UI层再调用增删改查,整个过程非常的繁琐,开发效率并不是很高,这种项目做久了之后,就非常的痛苦,非常的无聊。今天给大家带来一个抽象出增 删改查的框架,相信有些大牛早就总结出来了,不喜勿喷哈,本人旨在分享。

 

AD:
 

 

相信经常做一些MS,CRM 项目的童鞋非常有体会,大部分时间都是在复制和粘贴,大部分项目框架都是建一个三层,首先是DAL建一些增删改查,然后呢是BLL业务层再建一些增删改 查,然后UI层再调用增删改查,整个过程非常的繁琐,开发效率并不是很高,这种项目做久了之后,就非常的痛苦,非常的无聊。今天给大家带来一个抽象出增 删改查的框架,相信有些大牛早就总结出来了,不喜勿喷哈,本人旨在分享。

 

让C#开发更简单,抽象增删改

 

你再也不用写增删改查了,抽象出来了!!

 

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

 

NetUtility.Dapper.Core.DataBaseAccess.cs

 

using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; using Dapper; using System.Data; using NetUtility.Entity; using System.Reflection; namespace NetUtility.Dapper.Core { ///  summary  /// 数据库访问类 ///  /summary  public class DataBaseAccess { public static SqlConnection CreateConnection() { string connStr = ConfigurationManager.ConnectionStrings[ connString ].ConnectionString; SqlConnection conn = new SqlConnection(connStr); conn.Open(); return conn; } ///  summary  /// 执行增、删、改方法 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static int Execute(string sql, object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.Execute(sql,parms); } } ///  summary  /// 得到单行单列 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static object ExecuteScalar(string sql, object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.ExecuteScalar(sql, parms); } } ///  summary  /// 单个数据集查询 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static List TEntity  Query TEntity (string sql,Func TEntity,bool  pre ,object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.Query TEntity (sql, parms).Where(pre).ToList(); } } ///  summary  /// 单个数据集查询 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static List TEntity  Query TEntity (string sql, object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.Query TEntity (sql, parms).ToList(); } } ///  summary  /// 多个数据集查询 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static SqlMapper.GridReader MultyQuery(string sql, object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.QueryMultiple(sql, parms); } } ///  summary  /// 单个数据集查询 ///  /summary  ///  param name= sql /param  ///  param name= parms /param  ///  returns /returns  public static TEntity FirstOrDefault TEntity (string sql,Func TEntity,bool  selector, object parms = null) { using (IDbConnection conn = CreateConnection()) { return conn.Query TEntity (sql, parms).Where(selector).FirstOrDefault(); } } } } 

 

把增删改查抽象出来了,少不了的就是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 TModel  where TModel : class { #region 数据库类型+DataBaseType ///  summary  /// 数据库类型 ///  /summary  public static string DataBaseType { get { string strType = ConfigurationManager.AppSettings[ DataBaseType ]; if (!string.IsNullOrEmpty(strType)) { return strType; } else { return string.Empty; } } } #endregion #region 主键属性字段+PrimaryKey ///  summary  /// 主键字段名称 ///  /summary  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 ///  summary  /// 获取表名 ///  /summary  ///  param name= prev 数据库表名前缀 /param  ///  returns /returns  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 ///  summary  /// Select 查询语句 ///  /summary  ///  returns /returns  public static string GetQuerySql() { StringBuilder sql = new StringBuilder( select * from  ); sql.Append(TableName()); return sql.ToString(); } #endregion #region Insert非Null属性的对象实例 Sql 语句+GetInsertSql ///  summary  /// Insert 非Null属性的对象实例 Sql 语句 ///  /summary  ///  param name= model /param  ///  returns /returns  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 ///  summary  /// Delete Sql 语句 ///  /summary  ///  returns /returns  public static string GetDeleteSql() { return string.Format(@ delete from {0} where {1} in @IdList , TableName(), PrimaryKey); } #endregion #region Update 非Null属性的对象实例 Sql语句+GetUpdateSql ///  summary  /// Update 非Null属性的对象实例 Sql语句 ///  /summary  ///  param name= model /param  ///  returns /returns  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 ///  summary  /// 非主键且非Null属性 ///  /summary  ///  param name= model /param  ///  returns /returns  public static string[] Propertys(TModel model) { PropertyInfo[] props = typeof(TModel).GetProperties(); List string  list = new List string  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)] ///  summary  /// 标识表名、主键等信息特性类 ///  /summary  public class TableInfoAttribute : Attribute { ///  summary  /// 数据库表名 ///  /summary  public string TableName { get; set; } ///  summary  /// 主键名称 ///  /summary  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)] ///  summary  /// 标识表名、主键等信息特性类 ///  /summary  public class TableInfoAttribute : Attribute { ///  summary  /// 数据库表名 ///  /summary  public string TableName { get; set; } ///  summary  /// 主键名称 ///  /summary  public string PrimaryKey { get; set; } public TableInfoAttribute() { } public TableInfoAttribute(string tableName, string key) { this.TableName = tableName; this.PrimaryKey = key; } } } 

 

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

 

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 TModel  where TModel : class { #region Insert非Null属性的对象实例+Insert(TModel model) ///  summary  /// Insert非Null属性的对象实例 ///  /summary  ///  param name= model /param  ///  returns /returns  public virtual int Insert(TModel model) { string sql = DataMapping TModel .GetInsertSql(model); object res = DataBaseAccess.ExecuteScalar(sql, model); if (res != null) { return Convert.ToInt32(res); } return 0; } #endregion #region Select * 查询+Query() ///  summary  /// Select * 查询 ///  /summary  ///  returns /returns  public virtual List TModel  Query() { string sql = DataMapping TModel .GetQuerySql(); return DataBaseAccess.Query TModel (sql); } #endregion #region 带查询条件的Select查询+Query(Func TModel, bool  selector) ///  summary  /// 带查询条件的Select查询 ///  /summary  ///  param name= selector /param  ///  returns /returns  public virtual List TModel  Query(Func TModel, bool  selector) { string sql = DataMapping TModel .GetQuerySql(); return DataBaseAccess.Query TModel (sql, selector); } #endregion #region 得到一个对象的实例+FirstOrDefault(Func TModel, bool  selector = null) ///  summary  /// 得到一个对象的实例 ///  /summary  ///  param name= selector /param  ///  returns /returns  public virtual TModel FirstOrDefault(Func TModel, bool  selector = null) { string sql = DataMapping TModel .GetQuerySql(); return DataBaseAccess.FirstOrDefault TModel (sql, selector); } #endregion #region 批量删除+Delete(string[] IdList) ///  summary  /// 批量删除 ///  /summary  ///  param name= IdList /param  ///  returns /returns  public virtual int Delete(string[] IdList) { return DataBaseAccess.Execute(DataMapping TModel .GetDeleteSql(), new { IdList = IdList }); } #endregion #region Update 一个非Null属性的对象+Update(TModel model) ///  summary  /// Update 一个非Null属性的对象 ///  /summary  ///  param name= model /param  ///  returns /returns  public virtual int Update(TModel model) { return DataBaseAccess.Execute(DataMapping TModel .GetUpdateSql(model), model); } #endregion #region 获取多个数据集+MultyQuery(string sql, object param = null) ///  summary  /// 获取多个数据集 ///  /summary  ///  param name= sql /param  ///  param name= param /param  ///  returns /returns  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 Student  { public override List Student  Query() { return base.Query(); } public List StudentInfo  QueryInfo() { string sql =  select * from Student a left join Classes b on a.ClassesId=b.Id ; using (IDbConnection conn = DataBaseAccess.CreateConnection()) { return conn.Query StudentInfo, Classes, StudentInfo (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(); } } } 

 

各位可以指出上面的程序一些毛病,相互交流一下,或者有什么更新的做法也可以说说

 

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat