快速开发框架第二弹:让ORM为快速开发插上翅膀(2)改进和基础框架搭建

  在上一篇的文章中,那样的封装让开发变的很爽,好吧,我承认这是面向数据库编程的思维。在一个类中,封装了单表的几乎所有操作,我的看法是,因为ORM封装了所有的与数据库打交道的操作,它就是项目中的数据交换层,由于这个泛型类封装了单对象的操作,那么使得我们独立了所有对象的基本操作,使复用达到最高,使我们关注点集中了在对象关系处理和复杂的业务逻辑中。(希望有经验的人能给我指导或者相互讨论)

一.让封装回归正途 多数据库的支持

    public class BaseDao<T> where T : Entity
    {
        public DbSession db;
        public BaseDao(DbSession _db) {
            db = _db;
        }

        public BaseDao(): this(DbSession.Default)
        { 
            
        }
        #region "查询"
        /// <summary>
        /// 通过条件得到对象
        /// </summary>
        /// <param name="where"></param>
        /// <returns>如果你的条件是得到单个 那么list《T》[0]就是这个对象</returns>
        public virtual List<T> Get_Entity_byWhere(WhereClip where, OrderByClip orderby, params Field[] fields)
        {
            return db.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 virtual DataTable Get_Entity_byWhere_ToTable(WhereClip where, OrderByClip orderby, params Field[] fields)
        {
            return db.From<T>()
                .Where(where)
                .Select(fields)
                .OrderBy(orderby)
                .ToTable();
        }
        /// <summary>
        /// 通过条件得到单个对象
        /// </summary>
        /// <param name="where"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public virtual T Get_SingleEntity_byWhere(WhereClip where, params Field[] fields)
        {
            return db.From<T>()
                .Where(where)
                .Select(fields)
                .ToSingle();
        }

        /// <summary>
        /// 得到所有的数据
        /// </summary>
        /// <returns>datatable</returns>
        public virtual DataTable Get_AllData_Table()
        {
            return db.From<T>().ToTable();
        }
        /// <summary>
        /// 得到所有的数据
        /// </summary>
        /// <returns>List<T></returns>
        public virtual List<T> Get_AllData_List()
        {
            return db.From<T>().ToList();
        }
        /// <summary>
        /// 得到top的几条数据
        /// </summary>
        /// <param name="top"></param>
        /// <param name="where"></param>
        /// <param name="orderby"></param>
        /// <returns></returns>
        public virtual List<T> Get_Entitys_ByTop(int top, WhereClip where, OrderByClip orderby, params Field[] fields)
        {
            if (top == 0) throw new Exception("top值不能为0");
            return db.From<T>()
                .Where(where)
                .Select(fields)
                .GetTop(top)
                .OrderBy(orderby)
                .ToList();
        }
        #endregion

        #region "更新"
        /// <summary>
        /// 更新一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Update_Entity(T entity)
        {
            entity.Attach();
            return db.Save<T>(entity) > 0;
        }
        /// <summary>
        /// 通过多个条件更新对象
        /// </summary>
        /// <param name="fields"></param>
        /// <param name="values"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual bool Update_Entity_byWhere(Field[] fields, object[] values, WhereClip where)
        {
            return db.Update<T>(fields, values, where) > 0;
        }
        /// <summary>
        /// 通过单个条件更新对象
        /// </summary>
        /// <param name="fields"></param>
        /// <param name="values"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual bool Update_Entity_byWhere(Field filed, object value, WhereClip where)
        {
            return db.Update<T>(filed, value, where) > 0;
        }

        #endregion

        #region "删除"
        /// <summary>
        /// 通过对象删除记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Delete_Entity(T entity)
        {
            return db.Delete<T>(entity) > 0;
        }

        /// <summary>
        /// 通过主键ID集合删除
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public virtual int Delete_Entitys(List<string> idList)
        {
            return Delete_Entitys(idList.ToArray());
        }
        /// <summary>
        /// 通过主键ID集合删除
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public virtual int Delete_Entitys(string[] idList)
        {
            return db.Delete<T>(idList);
        }
        /// <summary>
        /// 通过条件删除对象 如果批量删除可以传入条件 where = T.ID.in(obj[])
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual bool Delete_Entity(WhereClip where)
        {
            return db.Delete<T>(where) > 0;
        }
        #endregion

        #region "新增"
        /// <summary>
        /// add an new record,
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Add_Entity(T entity)
        {
            return db.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 virtual 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 virtual 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 virtual int Get_Entity_Record(WhereClip where)
        {
            return db.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 virtual List<T> Get_Entity_byPage(int currentPageindex, int pageSize,
            WhereClip where, OrderByClip orderby, params Field[] fields)
        {
            return db.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 virtual DataTable Get_Entity_byPage_ToTable(int currentPageindex, int pageSize,
            WhereClip where, OrderByClip orderby, params Field[] fields)
        {
            return db.From<T>()
                   .Where(where)
                   .Select(fields)
                   .OrderBy(orderby)
                   .GetPage(pageSize)
                   .ToTable(currentPageindex);
        }
        #endregion

        #region "批量处理"
        /// <summary>
        /// 带事物的批量添加
        /// </summary>
        /// <param name="entityList"></param>
        /// <returns></returns>
        public virtual bool BatchAdd_Entitys(List<T> entityList)
        {
            //使用事务进行批量数据插入
            using (DbTrans trans = db.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 virtual bool BatchUpdate_Entitys(List<T> entityList)
        {
            //使用事务进行批量数据更新
            using (DbTrans trans = db.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
    }

1.由于MySoft可以动态传入DbSession对象来支持不通的数据库操作,这里给先前的BaseDao类添加了一个带DbSession的构造函数,2.所有方法改成虚方法,使继承类可以重写自己的实现.在数据的业务逻辑操作类中,修改如下:

namespace Ecom.BusinessLogic.EshopManageMent
{
   
    public partial class e_ShopService : BaseDao<e_Shop>
    { 
        #region "ctor"
        //这里有多个数据库的操作情况,传入相应的数据库操作对象
        public e_ShopService() : base(DataAcess.DefaultSession) { }
        #endregion
    }
}

DaAcess 类如下:因为我这个项目有对多个数据库的操作,所以配置如下

public static class DataAcess
    {
        /// <summary>
        /// 通过配置节来实例化DbSession
        /// </summary>
        public static readonly DefaultSession DefaultSession = new DefaultSession();

        /// <summary>
        /// API基础数据库
        /// </summary>
        public static readonly DbSession TopSession = new DbSession("TopDataBaseCon");

        /// <summary>
        /// 跟踪基础库
        /// </summary>
        public static readonly DbSession TrackSession = new DbSession("TrackingCon");

    }

    public class DefaultSession : DbSession
    {
        public DefaultSession()
            : base("ApplicationServices")
{ this.RegisterSqlLogger(log => { //输出调试信息 ComLib.Debug.DebugView.PrintDebug(log); }); } }

二.项目规划

  

以Eshop模块为例,e_shop文件是mysoft生成的实体类,e_ShopService是生成的一般关系处理业务逻辑类(关系查询),e_ShopPartial是自己写的业务特殊业务处理类,2个类都是部分类,这样的分开是为了在让自己写的东西和生成的东西隔离,修改表结构或生成设置的时候不影响到现有代码。这里的命名规则如下,在eshop模块以下,全部的命名空间为

Ecom.BusinessLogic.EshopManageMent,使得我们处理的逻辑关注于模块的处理。

为什么要把CommonLibraries独立出一个文件夹,个人原因呢,因为东西是我写的,我希望调试的某些时候直接跟入源码,对源码BUG进行修改或者增加功能,如果是队友开发,将会把这些类库编译好的DLL全部放入Dependencies,Dependencies文件夹是为了让大家对项目依赖的DLL一目了然。

三.使用IOC,SingletonProvider来管理我们的业务逻辑

  1.为什么引入IOC: 在项目中,随处出现 logic a = new logic(); 这样的调用,每次调用一次业务,就要new一个实例出来,或者干脆在每个调用的类中写一个类全局变量,让全局调用,虽然这样的写法没问题,但是我觉得对于这种不需要保存状态的类,应该集体的进行管理,也不需要每次通过new得到实例,我的做法如下:

  IOC类的来源是:CommonLibrary.NET 中IOC模块

  2.为什么引入SingletonProvider,对于所有仅限于单线程操作的类,不需要去在每个类中去写相同的得到单列代码

public class PageServiceBase : Page
    {
        #region "通过容器获取类型实例"
        public e_ShopService MyEshopService
        {
            get
            {
                return Ioc.GetObject<e_ShopService>("e_ShopService");
            }
        }

        public e_IspService MyIspService
        {
            get
            {
                return Ioc.GetObject<e_IspService>("e_IspService");
            }
        }
        #endregion

        #region SingerInstance 如果类是单列模式 那么使用通用的 SingletonProvider获取实例
        //public e_ShopService MyInstanceShopService {
        //    get {
        //        return SingletonProvider<e_IspService>.Instance;
        //    }
        //}
        #endregion

    }

好吧,现在我所有继承这个page类的页面,要调用业务逻辑类只需要写 this.MyIspService.XXX();就OK了,清爽,方便,集中管理....

别忘记了,在Global文件中注册业务类.

   protected void Application_Start(object sender, EventArgs e)
        {
            Ioc.Init(new IocContainerInMemory());
            Ioc.AddObject("e_ShopService",new e_ShopService());
            Ioc.AddObject("e_IspService", new e_IspService());
        }
posted @ 2011-03-24 20:44  活雷锋  阅读(2357)  评论(2编辑  收藏  举报