HTML5技术

【.Net设计模式系列】工作单元(Unit Of Work)模式 ( 二 ) - Spacebar

字号+ 作者:H5之家 来源:博客园 2016-02-17 18:00 我要评论( )

回顾 在上一篇博客【.Net设计模式系列】仓储(Repository)模式 ( 一 ) 中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢@横竖都溢@浮云飞梦2位兄台对博文中存在的问题给予指出,并提供出好的解决方案,同时也感谢其他园友的支持。欢

回顾

在上一篇博客【.Net设计模式系列】仓储(Repository)模式 ( 一 )  中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢 @横竖都溢 @ 浮云飞梦 2位兄台对博文中存在的问题给予指出,并提供出好的解决方案,同时也感谢其他园友的支持。欢迎各位园友对博文中出现的错误或者是设计误区给予指出,一方面防止“误人子弟”,另一方面则可以让大家共同成长。

对于上一篇博客,只是给大家提供了一种对于小型项目数据访问层的一种实现方式,通过Sql语句和传递参数来实现CRUD。并未达到真正意义上的解耦。特此在本篇继续完善。

理论介绍

在进行数据库添加、修改、删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败。例如银行A、B两个账户的转账业务。一方失败都会导致事务的不完整性,从而事务回滚。而工作单元模式可以跟踪事务,在操作完成时对事务进行统一提交。

理论参考:

具体实践

首先,讲解下设计思想:领域层通过相应的库实现泛型仓储接口来持久化聚合类,之后在抽象库中将对泛型仓储接口提供基础实现,并将对应的实体转化为SQl语句。这样领域层就不需要操作Sql语句即可完成CRUD操作,同时使用工作单元对事务进行统一提交。

1)定义仓储接口,包含基本的CRUD操作及其重载不同的查询

IRepository<T> 2 { 插入对象 Insert(T entity); 更新对象 Update(T entity, Expression<Func<T, bool>> express); 删除对象 Delete(Expression<Func<T, bool>> express = null); 查询对象集合 List<T> QueryAll(Expression<Func<T, bool>> express = null); 查询对象集合 List<T> QueryAll(int index,int pagesize,List<PropertySortCondition> orderFields, Expression<Func<T, bool>> express = null); 查询对象集合 List<object> QueryAll(Type type, Expression<Func<T, bool>> express = null); 查询对象 T Query(Expression<Func<T, bool>> express); 查询数量 QueryCount(Expression<Func<T, bool>> express = null); 61 }

其次,对仓储接口提供基本实现,这里由于使用了Lambda表达式,所以就需要进行表达式树的解析(这里我希望园友能自己去研究)。

BaseRepository<T> : IRepository<T> 2 where T:class,new() 3 { 4 private IUnitOfWork unitOfWork; IUnitOfWorkContext context; BaseRepository(IUnitOfWork unitOfWork, IUnitOfWorkContext context) 9 { 10 this.unitOfWork = unitOfWork; 11 this.context = context; 12 } 13 14 Lazy<ConditionBuilder> builder = new Lazy<ConditionBuilder>(); tableName { { 19 TableNameAttribute attr= (TableNameAttribute)typeof(T).GetCustomAttribute(typeof(TableNameAttribute)); 20 return attr.Name; 21 } 22 } 插入对象 Insert(T entity) 29 { 30 Func<PropertyInfo[], string, IDictionary<string, object>, int> excute = (propertys, condition, parameters) => 31 { 32 List<string> names = new List<string>(); 33 foreach (PropertyInfo property in propertys) 34 { 35 if (property.GetCustomAttribute(typeof(IncrementAttribute)) == null) 36 { 37 string attrName = property.Name; 38 object value = property.GetValue(entity); , attrName)); 40 parameters.Add(attrName, value); 41 } 42 } ; , names), builder.Value.Condition); 45 return unitOfWork.Command(combineSql, parameters); 46 }; 47 return CreateExcute<int>(null, excute); 48 } 修改对象 Update(T entity, Expression<Func<T, bool>> express) 56 { 57 58 Func<PropertyInfo[], string, IDictionary<string, object>, int> excute = (propertys, condition, parameters) => 59 { 60 List<string> names = new List<string>(); 61 foreach (PropertyInfo property in propertys) 62 { 63 if (property.GetCustomAttribute(typeof(IncrementAttribute)) == null) 64 { 65 string attrName = property.Name; 66 object value = property.GetValue(entity); , attrName, attrName)); 68 parameters.Add(attrName, value); 69 } 70 } ; , names), builder.Value.Condition); 73 return unitOfWork.Command(combineSql, parameters); 74 }; 75 return CreateExcute<int>(express, excute); 76 } 删除对象 Delete(Expression<Func<T, bool>> express = null) 82 { 83 Func<PropertyInfo[], string, IDictionary<string, object>, int> excute = (propertys, condition, parameters) => 84 { ; 86 string combineSql = string.Format(sql, tableName, condition); 87 return unitOfWork.Command(combineSql, parameters); 88 }; 89 return CreateExcute<int>(express, excute); 90 } 查询对象集合 List<T> QueryAll(Expression<Func<T, bool>> express = null) 98 { 99 Func<PropertyInfo[], string, IDictionary<string, object>, List<T>> excute = (propertys, condition, parameters) => 100 { ; , propertys.Select(x => x.Name)), tableName, condition); 103 return context.ReadValues<T>(combineSql, parameters); 104 }; 105 return CreateExcute<List<T>>(express, excute); 106 } 查询对象集合(分页) List<T> QueryAll(int index,int pagesize,List<PropertySortCondition> orderFields,Expression<Func<T, bool>> express = null) 118 { 119 Func<PropertyInfo[], string, IDictionary<string, object>, List<T>> excute = (propertys, condition, parameters) => 120 { Exception(); } ; , propertys.Select(x => x.Name)),, orderFields), tableName, condition, (index - 1) * pagesize + 1, index * pagesize); 124 return context.ReadValues<T>(combineSql, parameters); 125 }; 126 return CreateExcute<List<T>>(express, excute); 127 } 查询对象集合 List<object> QueryAll(Type type, Expression<Func<T, bool>> express = null) 136 { 137 Func<PropertyInfo[], string, IDictionary<string, object>, List<object>> excute = (propertys, condition, parameters) => 138 { ; , propertys.Select(x => x.Name)), tableName, condition); 141 return context.ReadValues(combineSql, type, parameters); 142 }; 143 return CreateExcute<List<object>>(express, excute); 144 } 查询对象 T Query(Expression<Func<T, bool>> express) 152 { 153 Func<PropertyInfo[], string, IDictionary<string, object>, T> excute = (propertys, condition, parameters) => 154 { ; , propertys.Select(x => x.Name)), tableName, condition); 157 return context.ExecuteReader<T>(combineSql, parameters); 158 }; 159 return CreateExcute<T>(express, excute); 160 } 查询数量 QueryCount(Expression<Func<T, bool>> express = null) 168 { 169 Func<PropertyInfo[], string, IDictionary<string, object>, object> excute = (propertys, condition, parameters) => 170 { ; , propertys.Select(x => x.Name)), tableName, condition); 173 return context.ExecuteScalar(combineSql, parameters); 174 }; CreateExcute<object>(express, excute); 177 } TValue CreateExcute<TValue>(Expression<Func<T, bool>> express, Func<PropertyInfo[], string, IDictionary<string, object>, TValue> excute) 180 { 181 Dictionary<string, object> parameters = new Dictionary<string, object>(); 182 PropertyInfo[] propertys = typeof(T).GetProperties(); 183 string condition = ""; 184 if (express != null) 185 { 186 builder.Value.Build(express, tableName); , builder.Value.Condition); 188 for (int i = 0; i < builder.Value.Arguments.Length; i++) 189 { , i), builder.Value.Arguments[i]); 191 } 192 } 193 return excute(propertys, condition, parameters); 194 } 195 }

接下来,定义工作单元,所有的添加、删除、修改操作都会被储存到工作单元中。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    2017-05-02 11:02

  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    2017-04-28 14:02

网友点评