C#抽象增删改怎么实现
本篇内容主要讲解“C#抽象增删改怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#抽象增删改怎么实现”吧!
10年积累的成都网站建设、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有临泽免费网站建设让你可以放心的选择与我们合作。
现在业界火了一种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
{
///
/// 数据库访问类
///
public class DataBaseAccess
{
public static SqlConnection CreateConnection()
{
string connStr = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
return conn;
}
///
/// 执行增、删、改方法
///
///
///
///
public static int Execute(string sql, object parms = null)
{
using (IDbConnection conn = CreateConnection())
{
return conn.Execute(sql,parms);
}
}
///
/// 得到单行单列
///
///
///
///
public static object ExecuteScalar(string sql, object parms = null)
{
using (IDbConnection conn = CreateConnection())
{
return conn.ExecuteScalar(sql, parms);
}
}
///
/// 单个数据集查询
///
///
///
///
public static List
Query (string sql,Func pre ,object parms = null) {
using (IDbConnection conn = CreateConnection())
{
return conn.Query
(sql, parms).Where(pre).ToList(); }
}
///
/// 单个数据集查询
///
///
///
///
public static List
Query (string sql, object parms = null) {
using (IDbConnection conn = CreateConnection())
{
return conn.Query
(sql, parms).ToList(); }
}
///
/// 多个数据集查询
///
///
///
///
public static SqlMapper.GridReader MultyQuery(string sql, object parms = null)
{
using (IDbConnection conn = CreateConnection())
{
return conn.QueryMultiple(sql, parms);
}
}
///
/// 单个数据集查询
///
///
///
///
public static TEntity FirstOrDefault
(string sql,Func selector, object parms = null) {
using (IDbConnection conn = CreateConnection())
{
return conn.Query
(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 DataMappingwhere 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 ExecuteSqlwhere 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#抽象增删改怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
分享文章:C#抽象增删改怎么实现
网站地址:http://azwzsj.com/article/podsoc.html