[开源]Dapper Repository 一种实现方式
程序员文章站
2022-07-11 08:41:13
1. 接着上篇 "[开源]Entity Framework 6 Repository 一种实现方式" 2. 由于Dapper 本身就是轻量级Orm特性,这里参考 " Creating a Data Repository using Dapper " "dynamic queries in dappe ......
- 接着上篇[开源]entity framework 6 repository 一种实现方式
- 由于dapper 本身就是轻量级orm特性,这里参考creating a data repository using dapper 代码,来解决实体类与expression<func<t, bool>> predicate问题;
- 您可以通过nuget:install-package masterchief.dotnet.core.dapper;
- 您可以通过github:masterchief 查看具体源码以及单元测试;
- 欢迎star,欢迎issues;
插播一条求职
- 小弟拥有多年c#开发经验,从事过路灯,消防平台物联网平台开发,坐标上海;
- 如果贵司在招聘,烦请大佬考虑下,联系邮箱:meetyan@outlook.com;
基于dapper 的repository实现
public abstract class dapperdbcontextbase : idbcontext { #region constructors /// <summary> /// 构造函数 /// </summary> /// <param name="connectstring">连接字符串</param> protected dapperdbcontextbase(string connectstring) { connectstring = connectstring; } #endregion constructors #region properties /// <summary> /// 获取 是否开启事务提交 /// </summary> public idbtransaction currenttransaction { get; private set; } #endregion properties #region fields /// <summary> /// 当前数据库连接 /// </summary> public idbconnection currentconnection => transactionenabled ? currenttransaction.connection : createconnection(); /// <summary> /// 获取 是否开启事务提交 /// </summary> public bool transactionenabled => currenttransaction != null; /// <summary> /// 连接字符串 /// </summary> protected readonly string connectstring; #endregion fields #region methods /// <summary> /// 显式开启数据上下文事务 /// </summary> /// <param name="isolationlevel">指定连接的事务锁定行为</param> public void begintransaction(isolationlevel isolationlevel = isolationlevel.unspecified) { if (!transactionenabled) currenttransaction = createconnection().begintransaction(isolationlevel); } /// <summary> /// 提交当前上下文的事务更改 /// </summary> /// <exception cref="dataaccessexception">提交数据更新时发生异常:" + msg</exception> public void commit() { if (transactionenabled) try { currenttransaction.commit(); } catch (exception ex) { if (ex.innerexception?.innerexception is sqlexception sqlex) { var msg = databasehelper.getsqlexceptionmessage(sqlex.number); throw new dataaccessexception("提交数据更新时发生异常:" + msg, sqlex); } throw; } } /// <summary> /// 创建记录 /// </summary> /// <param name="entity">需要操作的实体类</param> /// <returns>操作是否成功</returns> public bool create<t>(t entity) where t : modelbase { validateoperator.begin().notnull(entity, "需要新增的数据记录"); // insert single data always return 0 but the data is inserted in database successfully //https://github.com/stackexchange/dapper/issues/587 //list<t> data = new list<t>() { entity }; return currentconnection.insert(new list<t> {entity}, currenttransaction) > 0; #region 测试代码 //string sql = @"insert into [dbo].[efsample] // ([id] // ,[createtime] // ,[modifytime] // ,[available] // ,[username]) //values // (@id // ,@createtime // ,@modifytime // ,@available // ,@username)"; //return currentconnection.execute(sql, entity) > 0; #endregion 测试代码 } /// <summary> /// 创建数据库连接idbconnection /// </summary> /// <returns></returns> public abstract idbconnection createconnection(); /// <summary> /// 删除记录 /// </summary> /// <returns>操作是否成功</returns> /// <param name="entity">需要操作的实体类.</param> public bool delete<t>(t entity) where t : modelbase { validateoperator.begin().notnull(entity, "需要删除的数据记录"); return currentconnection.delete(entity); } /// <summary> /// 执行与释放或重置非托管资源关联的应用程序定义的任务。 /// </summary> public void dispose() { if (currenttransaction != null) { currenttransaction.dispose(); currenttransaction = null; } currentconnection?.dispose(); } /// <summary> /// 条件判断是否存在 /// </summary> /// <returns>是否存在</returns> /// <param name="predicate">判断条件委托</param> public bool exist<t>(expression<func<t, bool>> predicate = null) where t : modelbase { var tablename = gettablename<t>(); var queryresult = dynamicquery.getdynamicquery(tablename, predicate); var result = currentconnection.executescalar(queryresult.sql, (object) queryresult.param, currenttransaction); return result != null; } /// <summary> /// 根据id获取记录 /// </summary> /// <returns>记录</returns> /// <param name="id">id.</param> public t getbykeyid<t>(object id) where t : modelbase { validateoperator.begin().notnull(id, "id"); return currentconnection.get<t>(id, currenttransaction); } /// <summary> /// 条件获取记录集合 /// </summary> /// <returns>集合</returns> /// <param name="predicate">筛选条件.</param> public list<t> getlist<t>(expression<func<t, bool>> predicate = null) where t : modelbase { var tablename = gettablename<t>(); var queryresult = dynamicquery.getdynamicquery(tablename, predicate); return currentconnection.query<t>(queryresult.sql, (object) queryresult.param, currenttransaction).tolist(); } /// <summary> /// 条件获取记录第一条或者默认 /// </summary> /// <returns>记录</returns> /// <param name="predicate">筛选条件.</param> public t getfirstordefault<t>(expression<func<t, bool>> predicate = null) where t : modelbase { var tablename = gettablename<t>(); var queryresult = dynamicquery.getdynamicquery(tablename, predicate); return currentconnection.queryfirst<t>(queryresult.sql, (object) queryresult.param, currenttransaction); } /// <summary> /// 条件查询 /// </summary> /// <returns>iqueryable</returns> /// <param name="predicate">筛选条件.</param> public iqueryable<t> query<t>(expression<func<t, bool>> predicate = null) where t : modelbase { throw new notimplementedexception(); } /// <summary> /// 显式回滚事务,仅在显式开启事务后有用 /// </summary> public void rollback() { if (transactionenabled) currenttransaction.rollback(); } /// <summary> /// 执行sql 脚本查询 /// </summary> /// <param name="sql">sql语句</param> /// <param name="parameters">参数</param> /// <returns>集合</returns> public ienumerable<t> sqlquery<t>(string sql, idbdataparameter[] parameters) { validateoperator.begin() .notnullorempty(sql, "sql语句"); var dataparameters = createparameter(parameters); return currentconnection.query<t>(sql, dataparameters, currenttransaction); } /// <summary> /// 根据记录 /// </summary> /// <returns>操作是否成功.</returns> /// <param name="entity">实体类记录.</param> public bool update<t>(t entity) where t : modelbase { validateoperator.begin().notnull(entity, "需要更新的数据记录"); return currentconnection.update(entity, currenttransaction); } private dapperparameter createparameter(idbdataparameter[] parameters) { if (!(parameters?.any() ?? false)) return null; var dataparameters = new dapperparameter(); foreach (var parameter in parameters) dataparameters.add(parameter); return dataparameters; } private string gettablename<t>() where t : modelbase { var tablecfginfo = attributehelper.get<t, tableattribute>(); return tablecfginfo != null ? tablecfginfo.name.trim() : typeof(t).name; } #endregion methods }
使用方法
public class sampleservice : isampleservice { private readonly idatabasecontextfactory _contextfactory; public sampleservice(idatabasecontextfactory contextfactory) { _contextfactory = contextfactory; } /// <summary> /// 创建 /// </summary> /// <param name="sample">efsample</param> /// <returns></returns> public bool create(efsample sample) { using (idbcontext context = _contextfactory.create()) { return context.create(sample); } } /// <summary> /// 条件查询 /// </summary> /// <param name="predicate">the predicate.</param> /// <returns></returns> /// <exception cref="notimplementedexception"></exception> public efsample getfirstordefault(expression<func<efsample, bool>> predicate = null) { using (idbcontext context = _contextfactory.create()) { return context.getfirstordefault(predicate); } } /// <summary> /// 根据主键查询 /// </summary> /// <param name="id">the identifier.</param> /// <returns></returns> /// <exception cref="notimplementedexception"></exception> public efsample getbykeyid(guid id) { using (idbcontext context = _contextfactory.create()) { return context.getbykeyid<efsample>(id); } } /// <summary> /// 条件查询集合 /// </summary> /// <param name="predicate">the predicate.</param> /// <returns></returns> public list<efsample> getlist(expression<func<efsample, bool>> predicate = null) { using (idbcontext context = _contextfactory.create()) { return context.getlist(predicate); } } /// <summary> /// 添加判断是否存在 /// </summary> /// <param name="predicate">the predicate.</param> /// <returns></returns> public bool exist(expression<func<efsample, bool>> predicate = null) { using (idbcontext context = _contextfactory.create()) { return context.exist(predicate); } } /// <summary> /// 脚本查询 /// </summary> /// <param name="sql">the sql.</param> /// <param name="parameter">dbparameter[]</param> /// <returns></returns> public list<efsample> sqlquery(string sql, dbparameter[] parameter) { using (idbcontext context = _contextfactory.create()) { return context.sqlquery<efsample>(sql, parameter)?.tolist(); } } /// <summary> /// 更新 /// </summary> /// <param name="sample">the sample.</param> /// <returns></returns> public bool update(efsample sample) { using (idbcontext context = _contextfactory.create()) { return context.update(sample); } } /// <summary> /// 事务 /// </summary> /// <param name="sample">the sample.</param> /// <param name="sample2">the sample2.</param> /// <returns></returns> public bool createwithtransaction(efsample sample, efsample sample2) { bool result; using (idbcontext context = _contextfactory.create()) { try { context.begintransaction();//开启事务 context.create(sample); context.create(sample2); context.commit(); result = true; } catch (exception) { context.rollback(); result = false; } } return result; } /// <summary> /// 删除 /// </summary> /// <param name="sample"></param> /// <returns></returns> public bool delete(efsample sample) { using (idbcontext context = _contextfactory.create()) { return context.delete(sample); } } }
结语
- dapper与entity framework都是通过irepository实现,所以您可以通过ioc切换;
- 该篇的单元测试写法与上篇一致;
- 小弟不才,大佬轻拍;