• DDD~基础设施层~续


    回到目录

    在之前写的DDD~基础设施层文章中,提到了UnitOfWork,它里面有一些方法,但经过项目证明,不应该有Save和IsExplicitSubmit,而这个工作单元只起到了数据上下文统一的作用,如A和B对象需要在同一个上下文中工作,这时,我们可以引用工作单元的概念,而对于保存和提交操作,还是应该在局部方法里完成的。

    为了不去触发MSDTC,我会封装一个特殊的事务,来实现这个工作,而对于SQL2008来说,可以直接使用.net自己的TransactionScope实现,对于同一个数据库来说,它不会被提升为分布式事务,而SQL2008以下的版本,则需要使用占占封装的事务,代码如下:

        /// <summary>
        /// Author:zhang.zhanling
        /// 同步文章:http://www.cnblogs.com/lori/p/3455393.html
        /// 对TransactionScope,让它对同一个数据库不产生msdtc服务
        /// </summary>
        public class TransactionScopeNoMsdtc
        {
            /// <summary>
            /// 产生包裹事务
            /// 支持LINQ表提交,并同时返回提交结果到实体
            /// </summary>
            /// <param name="db">数据上下文,多个方法使用的上下文必须是同一个</param>
            /// <param name="isOutermost">是否为最外层,默认为false</param>
            /// <param name="action">处理代码块</param>
            public static void UsingNoMsdtc(DbContext db, bool isOutermost, Action action)
            {
                var objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext;
                try
                {
                    if (objectContext.Connection.State == System.Data.ConnectionState.Closed)
                        objectContext.Connection.Open();
                    using (TransactionScope trans = new TransactionScope())
                    {
                        try
                        {
                            action();
                            trans.Complete();
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                        finally
                        {
                            trans.Dispose();
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (isOutermost)//如果是最外层事务,而将连接关闭
                    {
                        objectContext.Connection.Close();
                    }
                }
            }
            /// <summary>
            /// 产生包裹事务,它不是最外层的,如果是最外层的需要调用其它重载
            /// </summary>
            /// <param name="db">数据上下文,多个方法使用的上下文必须是同一个</param>
            /// <param name="action">处理代码块</param>
            public static void UsingNoMsdtc(DbContext db, Action action)
            {
                UsingNoMsdtc(db, false, action);
            }
        }

    而最新的IUnitOfWork接口就变成了一个标识接口,代码如下

        /// <summary>
        /// 数据上下文标识接口,它对于业务层应该是公开的
        /// 它对于实现上下文的方法,它并不关心,可以是linq2sql,ef,ado.net,nhibernate,memory,nosql等
        /// </summary>
        public interface IUnitOfWork
        {
        }

    我们看到,IUnitOfWork主要作用是标示各个仓储在同一个上下文当中,或者说,在一个工作单元之中,下面是项目中使用的代码,我们可以参考一下

        /// <summary>
        /// Point_Info仓储
        /// </summary>
        /// <remarks>create:cyr_(Ben)_20131128</remarks>
        public class Point_InfoRepository : TsingDa_NewLearningBarRepository<Point_Info>
        {
            #region Constructors
            public Point_InfoRepository() : this(null) { }
            public Point_InfoRepository(IUnitOfWork db) : base(db) { }
            #endregion
        }

    我们可以看到,上面的仓储提供了两个构造方法的实现,默认为空参,还有一个可以为它传入一个IUnitOfWork工作单元,本仓储也支持IoC的构造方法注入。

    回到目录

  • 相关阅读:
    新年新气象~
    北京不下雪,自己来点雪花看看吧~(附效果图)
    没事写个游戏自己玩~
    原生js实现简单的焦点图效果
    php xdebug扩展无法进入断点问题
    (转)没有IE就没有伤害!浏览器兼容性问题解决方案汇总
    利用mvc filterconfig属性实现权限验证
    c# 替换所有中文、标点符号,全角转半角
    go web 第三天 学习笔记 --mysql
    go web 第二天 学习笔记之文件上传
  • 原文地址:https://www.cnblogs.com/lori/p/3906534.html
Copyright © 2020-2023  润新知