用工作单元(IUnitOfWork)带给我们的是什么?

回到目录

用工作单元带给我们的是什么?... 1

1.     相关说明
2.     优化查询
3.     优化SubmitChanges
4.     优化TransactionScope
5.     核心代码

 

1.      相关说明

工作单元的接入,保证了数据上下文在一个操作单元中只有一个,它可以通过构造方法注入到其它类中,实现跨类进行方法的组合。

2.      优化查询

 

上面的问题产生的场合应该是:

你用了join语句,你的join语句与from语句所使用的数据上下文不是一个(DataContext)

解决方法:

将数据上下文变成一个就可以了,这就是之前我们一直用的线程单例模式出现的原因,而往往一个方法可能需要引用多个类中的方法,这时,线程单例将不能解决这个问题,这时,出现了IunitOfWork,工作单元的概念!

使用的场合:

BLL层引用多个BLL层的方法

BLL层引用多个DAL层的方法

可能出现的代码:

 

 

3.      优化SubmitChanges

将多个SubmitChanges语句合并成一个,然后提交意味着什么?它意味着你与数据库交互次数的降低,呵呵!

代码可能是这样:

 

4.      优化TransactionScope

对于不同数据上下文组合的事务来说,TransactionScope将会把它提升为分布式事务,这在MSDN上确实没有找到相关文档,只是实践证明出来的,呵呵,所以,对于使用TransactionScope的开发者来说,请同时使用IUnitOfWork模式吧,让不必出现的MSDTC不要随意出现!

 

 

5.      核心代码

BLL层基类:

  

 /// <summary>

    /// 业务层抽象基类

    /// </summary>

    public abstract class BLLBase

    {

        #region Constructors

        public BLLBase()

            : this(null)

        { }

 

        public BLLBase(IUnitOfWork iUnitOfWork)

        {

            this.UnitOfWork = iUnitOfWork;

            this.VMessage = new VMessage();

        }

        #endregion

 

        #region Fields & Properties

        /// <summary>

        /// 工作单元对象,由子类初始化

        /// </summary>

        protected IUnitOfWork UnitOfWork { get; private set; }

 

        /// <summary>

        /// XXB连接串

        /// </summary>

        protected static string XXBConn

        {

            get

            {

                if (System.Configuration.ConfigurationManager.ConnectionStrings["xxb"] == null)

                    throw new ArgumentException("请配置在config文件中的XXB节点");

                return System.Configuration.ConfigurationManager.ConnectionStrings["xxb"].ToString();

            }

        }

 

        /// <summary>

        /// 通用消息

        /// </summary>

        protected VMessage VMessage { get; set; }

        #endregion

 

        #region Methods

 

        /// <summary>

        ///  数据层统一操作对象实例

        ///  避免派生类直接new对象

        ///  </summary>

        /// <typeparam name="TEntity"></typeparam>

        /// <param name="iUnitOfWork"></param>

        /// <returns></returns>

        protected ICompleteRepository<TEntity> LoadRepository<TEntity>() where TEntity : class,Entity.IDataEntity

        {

            return UnitOfWork == null

                ? new EEE114Repository<TEntity>()

                : new EEE114Repository<TEntity>(UnitOfWork);

        }

        #endregion

 

    }

 

BLL层业务类继承BLLBase,可以使用LoadRepository泛型方法直接操作实体对象,如果BLL层业务对象为业务复杂的,在将来可能需要互相引用对方的,这时,我们需要在BLL类中进行构造方法的重构,为IUnitOfWork实例的注入预留接口。

#region Constructors

        public User_CourseManager()

            : this(null)

        {

 

        }

        public User_CourseManager(IUnitOfWork iUnitOfWork)

            : base(iUnitOfWork)

        {

            res_ItemCategory = new DAL.Res_ItemCategory(UnitOfWork);

            iResourceService = new Res_ItemService();

            user_CourseRepository = new DAL.User_Course(UnitOfWork);

            iCommon_CategoryServices = new BLL.Common_CategoryServices(UnitOfWork);

 

        }

        #endregion

有时,如果这个bll类需要使用BLLBase里的LoadRepository方法,需要为它的UnitOfWork属性赋值,为了保持代码的严禁性,我们只允许在基类构造方法中为它赋值,所以,一般bll子类的架构方法为:

public UserCenterManager()

            : base(new dbDataContext(XXBConn))

        {

            _user_Info = new User_Info(UnitOfWork);

            _user_Profile = new User_Profile(UnitOfWork);

            _user_SchoolInfo = new User_SchoolInfo(UnitOfWork);

        }

上面的代码中,同时展示了BLL是如何去引用DAL对象的,User_Info同时接收一个IunitOfWork对象,而它的代码为:

public partial class User_Course : EEE114Base

    {

        public User_Course(IUnitOfWork iUnitOfWork)

            : base(iUnitOfWork)

        {

 

        }

事实上,它是将EEE114Base基类中传递了一个数据上下文,这些数据上下文都会继承IunitOfWork这个接口,并最终实现统一的提交动作,我们在开发中,建议为每个DAL类型都保留一个带有IunitOfWork参数的架构方法,这样才能保存我们的LINQ操作共处于一个数据上下文。

 回到目录

posted @ 2013-03-26 11:14  张占岭  阅读(4625)  评论(1编辑  收藏  举报