当前位置: 首页 > news >正文

用工作单元(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操作共处于一个数据上下文。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:用工作单元(IUnitOfWork)带给我们的是什么?,如需转载请自行联系原博主。

相关文章:

  • EF架构~将数据库注释添加导入到模型实体类中
  • PHP生成随机字符串
  • JMeter接口测试中文乱码问题总结
  • loongson官方PMON使用
  • 系统单据号生成规则推荐
  • Saltstack-4:数据系统grains
  • 脚踏七彩Scala.js,进军前端娱乐圈
  • Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??
  • Shell命令-线上查询及帮助之man、help
  • 如何设置Apache虚拟域名
  • 总结下我遇到过的接口测试
  • interface和setter,getter
  • python之路---04 列表 元组
  • 学习进度条
  • MongoDB优化与一些需要注意的细节
  • [笔记] php常见简单功能及函数
  • 30天自制操作系统-2
  • Android优雅地处理按钮重复点击
  • CAP理论的例子讲解
  • JS函数式编程 数组部分风格 ES6版
  • Mysql5.6主从复制
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • opencv python Meanshift 和 Camshift
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • VUE es6技巧写法(持续更新中~~~)
  • 分布式事物理论与实践
  • - 概述 - 《设计模式(极简c++版)》
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 突破自己的技术思维
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 运行时添加log4j2的appender
  • 怎样选择前端框架
  • Java数据解析之JSON
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​学习一下,什么是预包装食品?​
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (二)WCF的Binding模型
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (转)setTimeout 和 setInterval 的区别
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .NET BackgroundWorker
  • .NET Core引入性能分析引导优化
  • .Net Winform开发笔记(一)
  • .net 获取url的方法
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .py文件应该怎样打开?
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @font-face 用字体画图标
  • @WebServiceClient注解,wsdlLocation 可配置
  • @拔赤:Web前端开发十日谈
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [C++]AVL树怎么转