MVC+Ef项目(3) 抽象数据库访问层的统一入口;EF上下文线程内唯一

抽象一个数据库访问层的统一入口(类似于EF的上下文,拿到上下文,就可以拿到所有的表).实际这个入口就是一个类,类里面有所有的仓储对应的属性.这样,只要拿到这个类的实例,就可以点出所有的仓储,我们在 Repository层里面添加一个类 DbSession.cs

namespace YouJiao.MvcWeb.Repository
{
    /// <summary>
    /// 相当于是简单工厂:通过DbSession可以拿到所有的仓储的实例,所以我们也可以将此DbSession看做是简单工厂.
    /// 职责:对整个数据库访问层做了高度抽象,它是整个数据库访问层的统一入口,BLL层来调用Repository层的时候
    /// 只要拿到DbSession就可以拿到所有的仓储,就可以对所有的表进行增删改查了
    /// </summary>
    public class DbSession : IDbSession   
    {
        public ObjectContext db = new ModelContainer();  //EF上下文 我们先直接new  后面再来修改成线程内唯一
        private IUserInfoRepository _userInfoRepository;
        public IUserInfoRepository UserInfoRepository
        {
            get
            {
                if (_userInfoRepository == null)
                {
                    _userInfoRepository = new UserInfoRepository();
                }
                return _userInfoRepository;
            }

            set
            {
                _userInfoRepository = value;
            }
        }

        private IProductRepository _productRepository;
        public IProductRepository ProductRepository
        {
            get
            {
                if (_productRepository == null)
                {
                    _productRepository = new ProductRepository();
                }
                return _productRepository;
            }
            set { _productRepository = value; }
        }

        //执行sql脚本
        public int ExecuteSql(string sql, ObjectParameter[] parameters)
        {
            return db.ExecuteFunction(sql, parameters);
        }

        //单元工作模式
        public int SaveChanges()
        {
            return db.SaveChanges();
        }
    }
}



然后我们抽象出一个接口,在 IRepository里面增加一个 IDbSession.cs

namespace YouJiao.MvcWeb.IRepository
{
    public interface IDbSession
    {
        IUserInfoRepository UserInfoRepository { get; set; }
        IProductRepository ProductRepository { get; set; }


        int ExecuteSql(string sql, ObjectParameter[] parameters);

        /// <summary>
        /// 将整个数据库访问层的所有修改都一次性的提交回数据库
        /// 业务逻辑层:一个业务场景,肯定会对多个表做修改,对多个表进行处理
        /// 此方法的存在:极大的提高数据库访问层批量提交sql的性能,提高数据库的吞吐量,减少跟数据库的交互次数
        /// </summary>
        /// <returns></returns>
        int SaveChanges();  //UnitWork模式
    }
}

这样结构就变成了下图所示

image

然后我们再来修改一下 EF上下文的实例,在BaseRepository和DbSession里面都有用到 上下文,我们要保证这个上下文在线程内是唯一的

image

image

我们在 Repository层,创建一个EF的简单工厂   实际也就是一个类(DbEfContextFactory),里面一个静态方法(GetCurrentDbEfContext)


namespace
YouJiao.MvcWeb.Repository { public class DbEfContextFactory { public static ObjectContext GetCurrentDbEfContext() { //CallContext:是线程内部唯一的独用的数据槽(一块内存空间) //传递dbcontext进去获取实例的信息,在这里进行强制转换。 ObjectContext context = (ObjectContext) CallContext.GetData("dbcontext"); if (context == null) //如果线程在数据槽里面没有此上下文 { context=new ModelContainer(); //那么我们自己就new一个 CallContext.SetData("dbcontext",context); //放到数据槽中 } return context; } } }

现在我们来修改一下刚才 DbSession.cs  和 BaseRepository.cs

namespace YouJiao.MvcWeb.Repository
{
    /// <summary>
    /// 相当于是简单工厂:通过DbSession可以拿到所有的仓储的实例,所以我们也可以将此DbSession看做是简单工厂.
    /// 职责:对整个数据库访问层做了高度抽象,它是整个数据库访问层的统一入口,BLL层来调用Repository层的时候
    /// 只要拿到DbSession就可以拿到所有的仓储,就可以对所有的表进行增删改查了
    /// </summary>
    public class DbSession : IDbSession
    {
        public ObjectContext db
        {
            get
            {
                return DbEfContextFactory.GetCurrentDbEfContext();//EF上下文线程内唯一
            }
        }
        private IUserInfoRepository _userInfoRepository;
        public IUserInfoRepository UserInfoRepository
        {
            get
            {
                if (_userInfoRepository == null)
                {
                    _userInfoRepository = new UserInfoRepository();
                }
                return _userInfoRepository;
            }
            set{_userInfoRepository = value;}
        }

        private IProductRepository _productRepository;
        public IProductRepository ProductRepository
        {
            get
            {
                if (_productRepository == null)
                {
                    _productRepository = new ProductRepository();
                }
                return _productRepository;
            }
            set { _productRepository = value; }
        }

        //执行sql脚本
        public int ExecuteSql(string sql, ObjectParameter[] parameters)
        {
            return db.ExecuteFunction(sql, parameters);
        }

        //单元工作模式
        public int SaveChanges()
        {
            return db.SaveChanges();
        }
    }
}
namespace YouJiao.MvcWeb.Repository
{
    public class BaseRepository<T> where T : class   // 这里约束泛型T必须是个类 
    {
        private ObjectContext db
        {
            get
            {
                return DbEfContextFactory.GetCurrentDbEfContext();//获取EF上下文的实例
            }
        }

        public IList<T> LoadEneities(Func<T, bool> whereLambda)
        {
            return db.CreateObjectSet<T>().Where(whereLambda).ToList();
        }


        public IList<T> LoadPageEneities<S>(int pageSize, int pageIndex, out int total,
            Func<T, bool> whereLambda, Func<T, S> orderbyLambda, bool isAsc)
        {
            var tempList = db.CreateObjectSet<T>().Where(whereLambda).ToList();
            total = tempList.Count;
            if (isAsc)      //如果是升序
            {
                tempList = tempList.OrderBy(orderbyLambda)
                    .Skip(pageIndex * pageSize - 1)     //越过多少条
                    .Take(pageSize).ToList();           //取出多少条
            }
            else
            {
                tempList = tempList.OrderByDescending(orderbyLambda)
                    .Skip(pageIndex * pageSize - 1)
                    .Take(pageSize).ToList();
            }
            return tempList;
        }

        public T AddEntity(T model)
        {
            db.CreateObjectSet<T>().AddObject(model);
            db.SaveChanges();
            return model;
        }

        public bool DeleteEntity(T model)
        {
            db.CreateObjectSet<T>().Attach(model);
            db.ObjectStateManager.ChangeObjectState(model, EntityState.Deleted);
            return db.SaveChanges() > 0;
        }

        public bool UpdateEntity(T model)
        {
            db.CreateObjectSet<T>().Attach(model);
            db.ObjectStateManager.ChangeObjectState(model, EntityState.Modified);
            return db.SaveChanges() > 0;
        }
    }
}
原文地址:https://www.cnblogs.com/joeylee/p/3626199.html