在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码。在这个教程中,你将要看到使用仓储和工作单元模式进行增、删、改、查的一些方法。像前面的教程一样,你将要修改已经创建的页面中代码的工作方式,而不是新创建的页面。
9-1 仓储和工作单元模式
仓储和工作单元模式用来在数据访问层和业务逻辑层之间创建抽象层。实现这些模式有助于隔离数据存储的变化,便于自动化的单元测试或者测试驱动的开发 ( TDD )。 在这个教程中,你将要为每个实体类型实现一个仓储类。对于 Student 实体来说,你需要创建一个仓储接口和一个仓储类。当在控制器中实例化仓储对象的时候。你将会通过接口来使用它,当控制器在 Web 服务器上运行的时候,控制器将会接受任何实现仓储接口的对象引用。通过接收仓储对象进行数据的存储管理,使得你可以容易地控制测试,就像使用内存中的集合一样。 在教程的最后,你将要在 Course 控制器中对 Course 和 Department 实体使用多个仓储和一个工作单元类。工作单元类则通过创建一个所有仓储共享的数据库上下文对象,来组织多个仓储对象。如果你希望执行自动化的单元测试,你也应该对 Student类通过相同的方式创建和使用接口。不管怎样,为了保持教程的简单,你将不会通过接口创建和使用这些类。 下面的截图展示了在控制器和上下文之间的概念图,用来比较与不使用仓储或工作单元模式的区别。
在这个教程中不会创建单元测试,在 MVC 应用中使用仓储模式进行 TDD 的相关信息,可以查看 MSDN 网站中的 Walkthrough: Using TDD with ASP.NET MVC ,EF 团队博客中的 Using Repository and Unit of Work patterns with Entity Framework 4.0 ,以及 Julie Lerman 的博客 Agile Entity Framework 4 Repository 系列。 注意:有多种方式可以实现仓储和工作单元模式。配合工作单元类可以使用也可以不使用仓储类。可以对所有的实体类型实现一个简单的仓储,或者每种类型一个。如果为每种类型实现一个仓储,还可以通过分离的类,或者泛型的基类然后派生,或者抽象基类然后派生。可以将业务逻辑包含在仓储中,或者限制只有数据访问逻辑。也可以通过在实体中使用 IDbSet 接口代替 DbSet 类为数据库上下文类创建一个抽象层。在这个教程中展示的目标实现了抽象层,只是其中一种考虑,并不是针对所有的场景和环境都适用。
9-2 创建 Student 仓储类
在 DAL 文件夹中,创建一个文件名为 IStudentRepository.cs 的文件,将当前的代码使用如下代码替换。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using ContosoUniversity.Models; namespace ContosoUniversity.DAL { public interface IStudentRepository : IDisposable { IEnumerable<Student> GetStudents(); Student GetStudentByID(int studentId); void InsertStudent(Student student); void DeleteStudent(int studentID); void UpdateStudent(Student student); void Save(); } }
代码定义了一套典型的增、删、改、查方法。包括两个读取方法 – 一个返回所有的学生实体,一个通过 ID 查询单个实体。 在 DAL 文件夹中,创建名为 StudentRepository.cs 的类文件,使用下面的代码替换原有的代码,这个类实现了 IStudentRepository 接口。
using System; using System.Collections.Generic; using System.Linq; using System.Data; using ContosoUniversity.Models; namespace ContosoUniversity.DAL { public class StudentRepository : IStudentRepository, IDisposable { private SchoolContext context; public StudentRepository(SchoolContext context) { this.context = context; } public IEnumerable<Student> GetStudents() { return context.Students.ToList(); } public Student GetStudentByID(int id) { return context.Students.Find(id); } public void InsertStudent(Student student) { context.Students.Add(student); } public void DeleteStudent(int studentID) { Student student = context.Students.Find(studentID); context.Students.Remove(student); } public void UpdateStudent(Student student) { context.Entry(student).State = EntityState.Modified; } public void Save() { context.SaveChanges(); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { context.Dispose(); } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索context
, student
, 仓储
, 一个
, 仓储类
, 实体
单元
,以便于您获取更多的相关知识。