ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装
1. EFContextFactory线程内唯一复习
(1)在这里我们再解释一下线程内唯一,拿用老师的说法就是,假设这个线程就是衣服,而每件衣服上面都有口袋,那么我们就可以把这个口袋看成数据槽(CallContext指向的那一块内存空间),每件衣服都会有自己的口袋(特殊的除外),而这时候你要从衣服口袋里面拿出去一个糖,这时候我要先去口袋里面检查检查有没有,如果衣服口袋里面有我们就拿出来,负责我先将糖放到衣服口袋里,你下次来的时候继续在判断有没有。而且每件衣服都有自己独立的口袋,他们是没有任何关联的,着就保证了每件衣服内都会有糖(线程内唯一)。
(2)CallContext可以帮助我们保证线程内唯一。
2.DbSession
(1)在DbSession中封装了我们所有仓储的属性,在属性里面我们能够拿到我们仓储的实例,那么DbSession可以看成是我们整个数据库访问层的统一入口,另外在DbSession里面我们有封装了一个SaveChanges方法,那么在SaveChanges里面怎么做呢?请看下面的代码:
namespace LYZJ.UserLimitMVC.DAL
{
//一次跟数据库交互的会话
public class DbSession //代表应用程序跟数据库之间的一次会话,也是数据库访问层的统一入口
{
public IDAL.IRoleRepository RoleRepository
{
get { return new RoleRepository(); }
}
public IDAL.IUserInfoRepository UserInfoRepository
{
get { return new UserInfoRepository(); }
}
//代表:当前应用程序跟数据库的绘画内所有的实体的变化,更新会数据库
public int SaveChanges()
{
//调用EF上下文的SaveChanges方法
return DAL.EFContextFactory.GetCurrentDbContext().SaveChanges();
}
}
} (2)我们封装了一个SaveChanges方法的话,它就直接去获取当前线程里面的上下文,然后调用上下文的SaveChanges方法,就相当于直接把当前线程内部所有实体的改变提交到数据库里面,看上面的代码可能大部人都没有什么感觉,这是干什么呢?这时候我在作一个工作,就是将BaseRepository(仓储)中增删改方法的db.SaveChanges()删除掉,这时候我们就发现好处了吧,那就是我们数据库访问层虽然调用的方法没有真正的保存到数据库里面去,也就是把SaveChanges全部给放到DbSession中去实现了,那么DbSession我们就能够看成一个真正的会话了。
(3)也就是说我们在前面调用了很多次的增删改的实体之后(操作很多表),而只需要去DbSession中调用一个SaveChanges方法,就可以把所有的表实体的变化都放到数据库中去。
3.将SaveChanges方法放到DbSession中好处
(1)那么我们将SaveChanges方法放到DbSession中有什么好处呢?我们再项目中举个例子来说:我们回到BaseService里面拿添加仓储来说,假设我们添加实体这里,我们再上面做了一个添加用户的实体,然后我们业务里面还有修改一个状态,那么我们的代码如下所示:
1 //实现对数据库的添加功能
2
3 public T AddEntity(T entity)
4
5 {
6
7 //调用T对应的仓储来做添加工作
8
9 CurrentRepository.AddEntity(entity);
10
11 CurrentRepository.UpdateEntity(entity);
12
13 } (2)在这里我们一个业务场景可能会操作很多个表,在之前的做法中我们所有的增删改方法每调用一次就会执行SaveChanges一次,比如添加用户当我们添加用户就要SaveChangers一次,然后付给权限有需要一次,那这样的话就跟数据库交互了很多次,那么我们就才想到将SaveChangers方法提取到DbSession中去。
(3)如果我们将SaveChangers提取到DbSession中去的话,那么当我们以后操作多个实体之后直接来调用一下DbSession实现,这时候对应的上面的添加的方法即可这样实现:
1 //DbSession的存放
2
3 public DbSession _DbSession = new DbSession();
4
5 //基类的构造函数
6
7 public BaseService()
8
9 {
10
11 SetCurrentRepository(); //构造函数里面去调用了,此设置当前仓储的抽象方法
12
13 }
14
15 public abstract void SetCurrentRepository(); //子类必须实现
16
17 //实现对数据库的添加功能
18
19 public T AddEntity(T entity)
20
21 {
22
23 //调用T对应的仓储来做添加工作
24
25 CurrentRepository.AddEntity(entity);
26
27 CurrentRepository.UpdateEntity(entity);
28
29 _DbSession.SaveChanges();
30
31 } (4)这时候我们将DbSession封装的话,这样就使的DbSession非常灵活,就是把SaveChangers的权利从数据库访问层提高到了业务逻辑层,让业务逻辑层来控制SaveChangers方法,而数据库访问层不需要进行SaveChangers方法了,那么就可以保证在一个业务场景中操作多个表只需要一次的提交,减少了跟数据库交互的次数。
4.对BaseService的修改
(1)通过上面的介绍,下面我们来对BaseService进行修改,修改的最终代码如下所示:
1 namespace LYZJ.UserLimitMVC.BLL
2
3 {
4
5 public abstract class BaseService<T> where T : class, new()
6
7 {
8
9 //当前仓储
10
11 public IDAL.IBaseRepository<T> CurrentRepository { get; set; }
12
13 //DbSession的存放
14
15 public DbSession _DbSession = new DbSession();
16
17 //基类的构造函数
18
19 public BaseService()
20
21 {
22
23 SetCurrentRepository(); //构造函数里面去调用了,此设置当前仓储的抽象方法
24
25 }
26
27 public abstract void SetCurrentRepository(); //子类必须实现
28
29 //实现对数据库的添加功能
30
31 public T AddEntity(T entity)
32
33 {
34
35 //调用T对应的仓储来做添加工作
36
37 &n
补充:Web开发 , ASP.Net ,