Unit Of Work之我见

本人以前写程序都是瞎写,根本没有啥模式也没有啥方法。

近一年来学习了传智的一些课程,感觉马伦老师很有才,很强大,所以学来了一个模式(应当叫模式吧,该我也不知道叫啥哈)。

就是在DAL层封装一个DbSession来为BLL提供访问统一入口:

public partial interface IDbSession
    {
        ObjectContext DbContext { get; }   //上下文对象
        int ExcuteSql(string sql, params ObjectParameter[] parameters);   //可以直接执行SQL语句
        int SaveChanges();    //统一提交更改
    }

这样来实现:

public partial class DbSession:IDbSession
    {

        public System.Data.Objects.ObjectContext DbContext
        {
             //这里用了一个工厂来取得DbContext,当时为了方便注入
            get { return DbContextFactory.GetCurrentDbContext(); }
        }

        public int ExcuteSql(string sql, params System.Data.Objects.ObjectParameter[] parameters)
        {
            return DbContext.ExecuteFunction(sql, parameters);
        }

        public int SaveChanges()
        {
            return DbContext.SaveChanges();
        }
        
    }

使用时DAL层全部返回true,是否有问题交给BLL来处理

public class BaseRepository<T> : IBaseRepository<T> where T : class,new() 
    {
        private readonly ObjectContext _db = DbContextFactory.GetCurrentDbContext();

        public bool AddEntities(ICollection<T> entities)
        {
            foreach (var entity in entities)
            {
                AddEntity(entity);
            }
            return true;
        }
  }
public  class BaseService<T> : IBaseService<T> where T : class,new()
    {
      .....

      public bool AddEntities(ICollection<T> entities)
        {
            CurrentRepository.AddEntities(entities);
            return TryToSave();
        }

       private bool TryToSave()
        {
            try
            {
                CurrentDbSession.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
}

 这样,可以多次提交,只有在需要的时候,统一发送到数据库,可以算上Unit Of Work了。

但今天又发现一个好东西,可以再加一个事务进去,其实本身EF就会做事务处理了,但为了好扩展,自己加一个更好些,改造下接口:

记得添加System.Transactions引用并Using

public partial interface IDbSession
    {
        ObjectContext DbContext { get; }
        int ExcuteSql(string sql, params ObjectParameter[] parameters);
        //执行事务
        TransactionScope CreateTransaction(IsolationLevel isolationLevel, int timeoutInSeconds);
        int SaveChanges();
    }

实现它:

public partial class DbSession:IDbSession
    {

        public System.Data.Objects.ObjectContext DbContext
        {
            get { return DbContextFactory.GetCurrentDbContext(); }
        }

        public int ExcuteSql(string sql, params System.Data.Objects.ObjectParameter[] parameters)
        {
            return DbContext.ExecuteFunction(sql, parameters);
        }

        public int SaveChanges()
        {
            return DbContext.SaveChanges();
        }

        //执行事务(级别,超时时间)
        public TransactionScope CreateTransaction(IsolationLevel isolationLevel, int timeoutInSeconds)
        {
            var option = TransactionScopeOption.Required;
            var options = new TransactionOptions
                {
                    IsolationLevel = isolationLevel,
                    Timeout = new TimeSpan(0, 0, timeoutInSeconds)
                };
            return new TransactionScope(option, options);
        }
    }

 

 这回可以这样调用了:

            if (isAddNew)
            {
                using (var scope = dbSession.CreateTransaction(System.Transactions.IsolationLevel.ReadCommitted, 600))
                {
                    ....

                    dbSession.SaveChanges();

                    .....

                    dbSession.SaveChanges();
                    scope.Complete();
                }
            }


说的语无伦次,仅作笔记 ^^

posted @ 2013-09-13 16:54  AaronYu  阅读(548)  评论(0编辑  收藏  举报