快速开发框架第二弹:让ORM为快速开发插上翅膀(1)
本来这想写通用类库和通用控件,想想还是算了.通用类库是在自己平时积攒的通用方法基础上集合一些开源项目,开源项目列举如下:Discuze,CommonLibrary.NET,.NET Extensions.....,另外整合进了Log4Net,和几个开源组件,恩,拿来主义.好吧,现在开始这篇文章
ORM的选择
我是一个ORM的粉丝,用过llblgen,Nber,iBatis,SubSonic,Hxj.Data,最终选择了MySoft,原因如下,不喜欢结合XML配置的数据库访问方法,不喜欢对像拖对象的懒加载方式,不喜欢在每次更新前还需要查询数据库,不喜欢在强类型的ORM语法中还加上字符。好吧,MySoft除了._.很囧之外,不管语法还是上手度,是我最喜欢的.有兴趣可以看MySoft的作者毛哥的博客.这篇文章不讨论用法,只是提一个思路,你喜欢其它的ORM也没有关系,萝卜白菜嘛. 再次强调,个人喜好!
封装再封装
//得到一个对象 Products entity = BaseDao<Products>.Get_SingleEntity_byWhere(Products._.ProductID == parID); //更新一个对象 Products entity = Fill_Entity();//给实体对象赋值 省略了方法 BaseDao<Products>.Update_Entity(entity); //删除ID 满足条件如 1,2,3中的所有数据 BaseDao<Products>.Delete_Entity(Products._.ProductID.In(strIDsCollection.Split(','))); //单表的分页 带条件 带排序 后面文章讨论多表情况 var entityList = BaseDao<Products>.Get_Entity_byPage(currentPageIndex, pageSize, where, orderby);
上面只列举了几个操作,由于所有的单表操作BaseDao全部搞定了,事务,批量操作也封装在里面,由于BaseDao是泛型类,下面方法中的Where条件,OrderBy条件,需要查询的字段都是活的,使得我们在写单表操作的时候如鱼得水。BaseDao的代码如下:
public class BaseDao<T> where T : Entity { #region "查询" /// <summary> /// 通过条件得到对象 /// </summary> /// <param name="where"></param> /// <returns>如果你的条件是得到单个 那么list《T》[0]就是这个对象</returns> public static List<T> Get_Entity_byWhere(WhereClip where, OrderByClip orderby, params Field[] fields) { return DbSession.Default.From<T>() .Where(where) .Select(fields) .OrderBy(orderby) .ToList(); } /// <summary> /// 得到DataTable数据集合 /// </summary> /// <param name="where"></param> /// <param name="orderby"></param> /// <param name="fields"></param> /// <returns></returns> public static DataTable Get_Entity_byWhere_ToTable(WhereClip where, OrderByClip orderby, params Field[] fields) { return DbSession.Default.From<T>() .Where(where) .Select(fields) .OrderBy(orderby) .ToTable(); } /// <summary> /// 通过条件得到单个对象 /// </summary> /// <param name="where"></param> /// <param name="fields"></param> /// <returns></returns> public static T Get_SingleEntity_byWhere(WhereClip where, params Field[] fields) { return DbSession.Default.From<T>() .Where(where) .Select(fields) .ToSingle(); } /// <summary> /// 得到所有的数据 /// </summary> /// <returns>datatable</returns> public static DataTable Get_AllData_Table() { return DbSession.Default.From<T>().ToTable(); } /// <summary> /// 得到所有的数据 /// </summary> /// <returns>List<T></returns> public static List<T> Get_AllData_List() { return DbSession.Default.From<T>().ToList(); } /// <summary> /// 得到top的几条数据 /// </summary> /// <param name="top"></param> /// <param name="where"></param> /// <param name="orderby"></param> /// <returns></returns> public static List<T> Get_Entitys_ByTop(int top, WhereClip where, OrderByClip orderby, params Field[] fields) { if (top == 0) throw new Exception("top值不能为0"); return DbSession.Default.From<T>() .Where(where) .Select(fields) .GetTop(top) .OrderBy(orderby) .ToList(); } #endregion #region "更新" /// <summary> /// 更新一条记录 /// </summary> /// <param name="entity"></param> /// <returns></returns> public static bool Update_Entity(T entity) { entity.Attach(); return DbSession.Default.Save<T>(entity) > 0; } /// <summary> /// 通过多个条件更新对象 /// </summary> /// <param name="fields"></param> /// <param name="values"></param> /// <param name="where"></param> /// <returns></returns> public static bool Update_Entity_byWhere(Field[] fields, object[] values, WhereClip where) { return DbSession.Default.Update<T>(fields, values, where) > 0; } /// <summary> /// 通过单个条件更新对象 /// </summary> /// <param name="fields"></param> /// <param name="values"></param> /// <param name="where"></param> /// <returns></returns> public static bool Update_Entity_byWhere(Field filed, object value, WhereClip where) { return DbSession.Default.Update<T>(filed, value, where) > 0; } #endregion #region "删除" /// <summary> /// 通过对象删除记录 /// </summary> /// <param name="entity"></param> /// <returns></returns> public static bool delete_Entity(T entity) { return DbSession.Default.Delete<T>(entity) > 0; } /// <summary> /// 通过主键ID集合删除 /// </summary> /// <param name="idList"></param> /// <returns></returns> public static int Delete_Entitys(List<string> idList) { return Delete_Entitys(idList.ToArray()); } /// <summary> /// 通过主键ID集合删除 /// </summary> /// <param name="idList"></param> /// <returns></returns> public static int Delete_Entitys(string[] idList) { return DbSession.Default.Delete<T>(idList); } /// <summary> /// 通过条件删除对象 如果批量删除可以传入条件 where = T.ID.in(obj[]) /// </summary> /// <param name="where"></param> /// <returns></returns> public static bool Delete_Entity(WhereClip where) { return DbSession.Default.Delete<T>(where) > 0; } #endregion #region "新增" /// <summary> /// add an new record, /// </summary> /// <param name="entity"></param> /// <returns></returns> public static bool Add_Entity(T entity) { return DbSession.Default.Save<T>(entity) > 0; } #endregion #region "分页" /// <summary> /// 分页显示数据 需要记录总数 /// </summary> /// <param name="currentPageindex">当前页码</param> /// <param name="pageSize">pagesize</param> /// <param name="where">WhereClient</param> /// <param name="orderby">OrderByClip</param> /// <param name="record">总的记录数</param> /// <returns></returns> public static List<T> Get_Entity_byPage(int currentPageindex, int pageSize, WhereClip where, OrderByClip orderby, out int record, params Field[] fields) { record = Get_Entity_Record(where); return Get_Entity_byPage(currentPageindex, pageSize, where, orderby, fields); } /// <summary> /// 分页 返回Datatable /// </summary> /// <param name="currentPageindex"></param> /// <param name="pageSize"></param> /// <param name="where"></param> /// <param name="orderby"></param> /// <param name="record">总记录</param> /// <param name="fields"></param> /// <returns></returns> public static DataTable Get_Entity_byPage_ToTable(int currentPageindex, int pageSize, WhereClip where, OrderByClip orderby, out int record, params Field[] fields) { record = Get_Entity_Record(where); return Get_Entity_byPage_ToTable(currentPageindex, pageSize, where, orderby, fields); } /// <summary> /// 通过条件得到表的记录数 /// </summary> /// <param name="where"></param> /// <returns></returns> public static int Get_Entity_Record(WhereClip where) { return DbSession.Default.From<T>().Where(where).Count(); } /// <summary> /// 分页显示数据 不需要记录总数 /// </summary> /// <param name="currentPageindex">当前页码<</param> /// <param name="pageSize">pagesize</param> /// <param name="where">WhereClient</param> /// <param name="orderby">OrderByClip</param> /// <returns></returns> public static List<T> Get_Entity_byPage(int currentPageindex, int pageSize, WhereClip where, OrderByClip orderby, params Field[] fields) { return DbSession.Default.From<T>() .Where(where) .Select(fields) .OrderBy(orderby) .GetPage(pageSize) .ToList(currentPageindex); } /// <summary> /// 分页返回Datatable /// </summary> /// <param name="currentPageindex"></param> /// <param name="pageSize"></param> /// <param name="where"></param> /// <param name="orderby"></param> /// <param name="fields"></param> /// <returns></returns> public static DataTable Get_Entity_byPage_ToTable(int currentPageindex, int pageSize, WhereClip where, OrderByClip orderby, params Field[] fields) { return DbSession.Default.From<T>() .Where(where) .Select(fields) .OrderBy(orderby) .GetPage(pageSize) .ToTable(currentPageindex); } #endregion #region "批量处理" /// <summary> /// 带事物的批量添加 /// </summary> /// <param name="entityList"></param> /// <returns></returns> public static bool BatchAdd_Entitys(List<T> entityList) { //使用事务进行批量数据插入 using (DbTrans trans = DbSession.Default.BeginTrans()) { try { DbBatch batch = trans.BeginBatch(entityList.Count); entityList.ForEach(item => { item.Detach(); batch.Save(item); }); batch.Process(); trans.Commit(); return true; } catch { trans.Rollback(); return false; } } } /// <summary> /// 批量更新 /// </summary> /// <param name="entityList"></param> /// <returns></returns> public static bool BatchUpdate_Entitys(List<T> entityList) { //使用事务进行批量数据更新 using (DbTrans trans = DbSession.Default.BeginTrans()) { try { DbBatch batch = trans.BeginBatch(entityList.Count); entityList.ForEach(item => { item.Attach(); batch.Save(item); }); batch.Process(); trans.Commit(); return true; } catch { trans.Rollback(); return false; } } } #endregion }
可以看到的是传入实体对象到这个类里面,条件,排序,要得到的字段都可以传入,使得这样的操作适合单表的绝大部分操作.
由于这样的封装和Orm的灵活性,使得项目层次变得很简单,业务层只需要关注复杂的业务逻辑和多表的关联.多表的关联在以后在说解决的办法.使用其它的ORM也可以做这样的封装,极大的提高工作效率.
老生常谈: 性能的问题
首先我想说的是,不要看到ORM就首先觉得ORM的效率是如何如何底下,权衡一下它所带来的工作效率的提升和开发模式的简洁,是否适合您的应用场景。况且很多性能问题我们可以用其它方式解决,比如说缓存方案,比如说并发数据插入的时候放入缓存定时定量一起提交,数据库读写分离等...