zoukankan      html  css  js  c++  java
  • MVC+EF之仓库模式

                                                                                                       仓库模式
    使用repository来将业务层和数据实体层分开来,业务逻辑层应该对组成数据源层的数据类型不可知,比如数据源可能是数据库或者Web service
    在数据源层和业务层之间增加一个repository层进行协调,有如下作用:
    1.从数据源中查询数据
    2.映射数据到业务实体
    3.将业务实体数据的修改保存到数据源 (持久化数据)
    这样repository就将业务逻辑和基础数据源的交互进行了分隔。
    数据和业务层的分离有如下三个优点:
    1.集中管理不同的底层数据源逻辑。
    2.给单元测试提供分离点。
    3.提供弹性架构,整体设计可以适应程序的不断进化。
    我们将会对原有做法进行两轮抽象,实现我们想要的效果。
    一、理论基础
    仓储和工作单元模式是用来在数据访问层和业务逻辑层之间创建一个抽象层。应用这些模式,可以帮助用来隔离你的程序在数据存储变化。
    二、准备工作
    首先我们先搭建好空的框架,准备基本的结构和一些测试数据。我们不再在第一阶段的MVCDemo上进行更改了, 重新建立一个新项目XEngine作为我们第二阶段的演示项目 。
    1.新建项目->ASP.NET Web应用程序->MVC
    2.新建Model(SysUser, SysRole , SysUserRole )
    3.安装EF,新建文件夹DAL,新建类 XEngineContext.cs ,新建类XEngineContext.cs
    4.修改HomeController.cs,运行Index视图,来生成数据库结构和测试数据。
    三、详细步骤
    第一轮抽象 : 解耦Controller和数据层对每一个实体类型建立一个对应的仓储类。以SysUser来说,新建一个仓储接口和仓储类。在controller中通过类似于下面这种方式使用:
    ISysUserRepository sysUserRepository = new SysUserRepository();
    具体做法:
    a.新建个文件夹 Repositories,后面新建的仓储类都放在这个文件夹中
    b.创建接口 ISysUserRepository接口中声明了一组典型的CRUD方法。其中查找方法有两个:返回全部和根据ID返回单个。
    c.创建对应的仓储类 SysUserRepository  创建类 SysUserRepository, 实现接口 ISysUserRepository
    d.Controller中使用SysUser仓储类  我们新建个Controller : UserController 用 List 模板生成视图。  
    注意:
    GC.SuppressFinalize(this);
    因为对象会被Dispose释放,所以需要调用GC.SuppressFinalize来让对象脱离终止队列,防止对象终止被执行两次。
    存在的两个问题:
    1.如果一个controller中用到多个repositories,每个都会产生一个单独的context
    2.每个entity type 都要实现一个对应的repository class ,这样会产生代码冗余。
    第二轮抽象:通过泛型消除冗余的repository class
    为每个 entity type 创建一个repository class 会
    a. 产生很多冗余代码
    b. 会导致不一致地更新
    解决a问题步骤:
    1.创建泛型接口 IGenericRepository
    2.创建对应的泛型仓储类 GenericRepository
    3.修改UserController 把原来的注释掉,给泛型类指定SysUser,主要更改部分如红线表示。前端不用做任何更改。
    解决b问题步骤:
    1.我们在DAL文件夹中新建一个类UnitOfWork用来负责context的一致性:
    当使用多个repositories时,共享同一个context,我们把使用多个repositories的一系列操作称为一个 unit of work.当一个unit of work完成时,我们调用context的SaveChanges方法来完成实际的更改。由于是同一个context, 所有相关的操作将会被协调好。
    这个类只需要一个Save方法和一组repository属性。每个repository属性返回一个repository实例,所有这些实例都会共享同样的context.
    2.把 GenericRepository.cs 中的Save 和 Dispose 删除, 移到UnitOfWork中。将IGenericRepository 中的IDisposable接口继承也去掉.Save & Dispose 的工作统一在UnitOfWork中完成。
    3.在UserController中使用UnitOfWork



  • 相关阅读:
    机器学习:贝叶斯分类器(一)——朴素贝叶斯分类器
    机器学习:kNN算法(二)—— 实战:改进约会网站的配对效果
    机器学习:kNN算法(一)—— 原理与代码实现(不调用库)
    Oracle给表设置自增字段
    IMAP、POP3、SMTP邮件服务器
    网站高并发大流量访问的10个处理及解决方案
    浅谈async/await
    【前端】加载的图片太多或者太大优化方案(上)
    【前端】本地调试H5页面方案总结
    alphafold2_conda版安装
  • 原文地址:https://www.cnblogs.com/xue-er/p/8023379.html
Copyright © 2011-2022 走看看