在EntityFramworkCore 配置种子数据中有降到如何配置种子数据,接下里就讲一讲数据仓储模式。

目录

1.动机

1.1 时下数据驱动应用是如何访问数据库

1.2Repository Design Pattern

2.实现

2.1具体仓储的实现

2.2泛型仓储


1.动机

1.1 时下数据驱动应用是如何访问数据库

传统的数据库应用结构如下:

从上图可以看出,对雇员的CURD操作是直接通过controller访问EFcore 的data context,EF将来自上层的CURD操作转化为SQL语句。那这样做有什么缺点呢:当然上述方法肯定是行之有效的,但是这样我们会把对数据的查询,修改,删除操作深度绑定到Controller这一层,这样的设计或者实现会造成代码冗余,且不利于后续维护,一旦数据访问逻辑发生了一点点小改动都需要对Controller进行修改。

1.2Repository Design Pattern

所以,这里就引入了数据仓储模式,这也是成为业界通用的做法,引入数据仓储模式后的架构如下:

简而言之就是我们在领域层和数据映射层之间加了一层,这一层类似于集合访问接口,专门用于领域层访问数据。换句话说,Repository Design Pattern在数据访问层和其它应用层之间扮演者一个中间人,应用获取数据的所有操作都交给这个中间人。好处是自然而然的将上层应用和低层数据访问隔离开来,当你改动一端时,不用修改另一端。而且测试Controller也会变得简单,你可以模拟一个内存数据库,而不用真的配置一个真实的数据库。

2.实现

2.1具体仓储的实现

为了方便依赖注入,我们首先定义一个仓库的接口:

简单起见我就定义下面几个方法(你可以根据具体的业务添加):

using RepositoryPatternStudy.Models;namespace RepositoryPatternStudy.Repository
{public interface IEmployeeRepository{IEnumerable<Employee> GetAll();Employee GetById(int id);void Insert(Employee employee);void Update(Employee employee);void Delete(Employee employee);void Save();}
}

下面添加具体的实现:

public class EmployeeRepository : IEmployeeRepository,IDisposable{private readonly EmployeeDbContext _context;public EmployeeRepository(EmployeeDbContext context){_context = context;}public void Delete(int employeeID){Employee employee = _context.Employees.Find(employeeID);_context.Employees.Remove(employee);}public IEnumerable<Employee> GetAll(){return _context.Employees.ToList();}public Employee? GetById(int id)=> _context.Employees.Find(id);public void Insert(Employee employee)=>_context.Employees.Add(employee);public void Save()=>_context.SaveChanges();public void Update(Employee employee)=>_context.Entry(employee).State=EntityState.Modified;public bool disposed=false;protected virtual void Dispose(bool disposing){if(!disposed){if(disposing)_context.Dispose();}disposed=true;}public void Dispose(){Dispose(true);GC.SuppressFinalize(this);}}

为了验证我们的正确性,我们可以新建一个EmployeeController:

 public class EmployeeController : Controller{private readonly IEmployeeRepository _employeeRepository;public EmployeeController(IEmployeeRepository employeeRepository)=>_employeeRepository = employeeRepository;[HttpGet]public List<Employee> Index(){var model=_employeeRepository.GetAll();return model.ToList();}
}

(在这里用了依赖注入,所以要记得在配置文件中添加服务:)

builder.Services.AddTransient<IEmployeeRepository,EmployeeRepository>();

运行程序打开Employee对于的页面:

可以看到成功的拿到了数据库的数据。至此具体的仓储就实现完成了!

当然,你可以添加相应的视图,使得显示效果更更好:

@model IEnumerable<RepositoryUsingEFinMVC.DAL.Employee>
@{ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>@Html.ActionLink("Add Employee", "AddEmployee")
</p>
<table class="table"><tr><th>@Html.DisplayNameFor(model => model.Name)</th><th>@Html.DisplayNameFor(model => model.Gender)</th><th>@Html.DisplayNameFor(model => model.Salary)</th><th>@Html.DisplayNameFor(model => model.Dept)</th><th></th></tr>@foreach (var item in Model){<tr><td>@Html.DisplayFor(modelItem => item.Name)</td><td>@Html.DisplayFor(modelItem => item.Gender)</td><td>@Html.DisplayFor(modelItem => item.Salary)</td><td>@Html.DisplayFor(modelItem => item.Dept)</td><td>@Html.ActionLink("Edit", "EditEmployee", new { EmployeeId = item.EmployeeID }) |@Html.ActionLink("Delete", "DeleteEmployee", new { EmployeeId = item.EmployeeID })</td></tr>}
</table>

显示效果如下:

2.2泛型仓储

因为我们只有一个实体类型:Employee,但实际上的项目实体肯定不止一个,可能还有订单order,顾客Custome等,如果没有泛型仓储,我们可能需要为每个实体构建一个仓库,这是很麻烦的。

有了前面的基础,我们构建泛型仓库就简单很多,首先定义一个泛型仓库接口:

    public interface IGenericRepository<T> where T:class{IEnumerable<T> GetAll();T GetById(object id);void Insert(T obj);void Update(T obj);void Delete(object id);void Save();}

然后实现它:

public class GenericRepository<T> : IGenericRepository<T> where T : class{private readonly EmployeeDbContext _context;private readonly DbSet<T> table;public GenericRepository(EmployeeDbContext context){_context = context;table = context.Set<T>();}public void Delete(object id){T existing=table.Find(id);table.Remove(existing);}public IEnumerable<T> GetAll()=>table.ToList();public T GetById(object id)=> table.Find(id);public void Insert(T obj)=>table.Add(obj);public void Save()=>_context.SaveChanges();public void Update(T obj){table.Attach(obj);_context.Entry(obj).State = EntityState.Modified;}}

将泛型仓储注册到服务:

builder.Services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));

然后在Controller中将泛型仓储替换原来的仓储:

 private readonly IEmployeeRepository _employeeRepository;private readonly IGenericRepository<Employee> _repository;public EmployeeController(IEmployeeRepository employeeRepository, IGenericRepository<Employee> genericRepository){_employeeRepository = employeeRepository;_repository = genericRepository;}[HttpGet]public ActionResult Index(){//var model=_employeeRepository.GetAll();var model = _repository.GetAll();return View(model);

可以得到相同的运行结果(我这里同时将两种类型的仓储都注册进去了)。

2.3 同时使用两种仓库

泛型仓储一般是比较通用的方法,也就是常见的CURD,一旦想定制化仓库,比扩展一些功能,则需要自行实现,但是如果已经有了泛型仓储,那么通过继承,我们可以只实现不同的部分,这样也带来了相当大的遍历。

操作如下:

    public interface IEmployeeRepositoryEx:IGenericRepository<Employee>{IEnumerable<Employee> GetEmployeesByGender(string gender);IEnumerable<Employee> GetEmployeesByDepartment(string Dept);}

上面是一个扩充了两个方法的新接口,其实现如下:

 public class EmployeeeRepositoryEx : GenericRepository<Employee>, IEmployeeRepositoryEx{// private readonly IGenericRepository<Employee> _repository;//  private readonly IEmployeeRepositoryEx _employeeRepositoryEx;private readonly EmployeeDbContext _context;public EmployeeeRepositoryEx(EmployeeDbContext context):base(context)//  IGenericRepository<Employee> genericRepository,IEmployeeRepositoryEx employeeRepositoryEx):base(context){//  _repository = genericRepository;//  _employeeRepositoryEx = employeeRepositoryEx;_context = context;}public IEnumerable<Employee> GetEmployeesByDepartment(string Dept){return _context.Employees.Where(x=>x.Dept == Dept);}public IEnumerable<Employee> GetEmployeesByGender(string gender){return _context.Employees.Where(x=>x.Gender == gender);}}

将IEmployeeRepository注册,并替换后,可以同时使用泛型接口和新接口的方法,从而达到了定制化扩展,同样你可以放在EmployeeController中尝试。


到此为止,仓储模型就基本讲完了,

EFCore的数据仓储模式相关推荐

  1. 数据仓储模式UnitOfWorks和Repository的实现

    数据仓储模式UnitOfWorks和Repository的实现( 网上看了相关内容关于UnitOfWorks和Repository的数据仓储模式的实现,也来动手搭建下. ORM使用微软自己的EF来实现 ...

  2. 仓储模式到底是不是反模式?

    [导读]仓储模式我们已耳熟能详,但当我们将其进行应用时,真的是那么得心应手吗?确定是解放了生产力吗?这到底是怎样的一个存在,确定不是反模式? 一篇详文我们探讨仓储模式,这里仅我个人的思考,若有更深刻的 ...

  3. .NET仓储模式高级用例

    \ 主要结论 \\ 如果需要执行基本CURD之外的其他操作,此时就有必要使用仓储(Repository).\\t 为了促进测试工作并改善可靠性,应将仓储视作可重复使用的库(Library).\\t 将 ...

  4. 使用实体框架、Dapper和Chain的仓储模式实现策略

    \ 关键要点: \ Dapper这类微ORM(Micro-ORM)虽然提供了最好的性能,但也需要去做最多的工作.\ 在无需复杂对象图时,Chain这类Fluent ORM更易于使用.\ 对实体框架(E ...

  5. 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  6. Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)

    很久没有写博客了,一些读者也经常问问一些问题,不过最近我确实也很忙,除了处理日常工作外,平常主要的时间也花在了继续研究微软的实体框架(EntityFramework)方面了.这个实体框架加入了很多特性 ...

  7. ASP.NET Core 中的规约模式(Specification Pattern )——增强泛型仓储模式

    原文链接:https://codewithmukesh.com/blog/specification-pattern-in-aspnet-core/ 在本文中,我们将讨论在 ASP.NET Core ...

  8. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用

    MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用 原文:MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用 摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. ...

  9. 云计算是否为数据仓储做好了准备呢?

    原文链接:http://blogs.sap.com/innovation/cloud-computing/is-cloud-ready-for-data-warehousing-022232<? ...

最新文章

  1. 20种看asp源码的方法及工具
  2. 一家全是学霸!王力宏的哥哥也是博士,近日获5000余万拨款用于这项研究
  3. python转exe 体积_[转]用PyInstaller将python转成可执行文件exe笔记
  4. poj 1328 Radar Installation
  5. Python-爬取中国天气网天气并通过邮箱定时发送
  6. Android Studio 的 build 过程
  7. 怎么才能学好Java编程写好Java代码?
  8. 监控oracle数据io,Prometheus监控Oracle数据库
  9. native 真机测试react_react-native真机调试出现Failed to install all
  10. Lubuntu16.4.3定制教程
  11. [云计算]网线的标签格式
  12. Android 11 Meetup 上海站!来了!
  13. [51nod]2128 前缀异或【数学题】
  14. JAVA随机数生成 | Math.random()方法 | 随机生成int、double类型
  15. java前端导入excel_Java之导入Excel Vue框架前端篇
  16. mysql只导出表数据_MySQL 如何只导出 指定的表 的表结构和数据 ( 转 )
  17. 如何搭建内测托管平台?有可以直接用的内测托管平台吗?
  18. linux sort排序及取前几条数据
  19. LA 3708 - Graveyard 墓地雕塑
  20. Zephyr 3.2 弃用devicetree 中node 里的label property

热门文章

  1. ORACLE +win2003 群集手记
  2. centos7-14-升级系统内核到最新版
  3. discuz所有版本通用!论坛后台SEO优化设置
  4. AI行业精选日报_人工智能(12·30)
  5. 面试中项目讲解的步骤
  6. python-turtle画铜钱古币
  7. HTML5+CSS大作业——明星薛之谦(7页面))带轮播特效
  8. 学习使用vim,以及各种vim插件(经典)
  9. Keepalived无法绑定VIP故障排查经历
  10. osgEarth资源链接