MVC中的Repository模式

1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository。

2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名为Repository来存放业务逻辑。

3.继续添加一个类库项目,命名为MyRepository.Domain,添加两个文件夹Models和Infrastructure。

Models来存放实体,Infrastructure来存放几个基本的类。现在目录结构已经搭建好了。

4.用NuGet确保三个项目添加了相同版本的EF,在MyRepository.DAL中引用MyRepository.Domain,在

MyRepository.Web中引用MyRepository.Domain和MyRepository.DAL。

5.在MyRepository.Domain中添加一个类BookStoreDbContext。使用EF来对数据库进行连接。

public class BookStoreDbContext : DbContext    {        //EF从配置文件中寻找name=BookStore的数据库链接。        //如果不指定: base("BookStore"),则寻找name=BookStoreDbContext的数据库连接        public BookStoreDbContext()            : base("BookStore")        {

        }    }

下面是配置文件:

  <connectionStrings>    <add name="BookStore" providerName="System.Data.SqlClient" connectionString="Data Source=.\sqlexpress;Initial Catalog=BookStore;User ID=Wangzx;Password=Wangzx01;Persist Security Info=True;"/>  </connectionStrings>

DbContext用来与数据库建立连接完成对数据的相关操作,如果不使用Repository模式,DbContext的实例化一般放在Controller中来使用。下面开始介绍MVC3中使用Repository模式。

先把Repository模式的类图贴出来:

6.先介绍最主要的接口IRepository,该接口定义了最通用的业务逻辑操作:增、删、该。这些操作对任何一个实体的操作都是一样的。该类添加在MyRepository.Domain项目的Infrastructure文件夹中。

下面是代码:

namespace MyRepository.Domain.Infrastructure{    public interface IRepository<TEntity> where TEntity : class    {        void Insert(TEntity entity);        void Update(TEntity entity);        void Delete(TEntity entity);    }}

这里使用泛型接口,可以用于Book,Author等不同实体的操作,只要把站位符替换掉即可。

7.下面是Repository泛型基类,它实现了IRepository接口,并使用的是泛型实现,用于对多个不同实体的操作。

具体的操作是通过DbContext来实现的,所以构造函数中要提供一个DbContext参数。该类与IRepository位于相同目录下面。

代码:

namespace MyRepository.Domain.Infrastructure{    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class    {        protected BookStoreDbContext dbContext;        protected DbSet<TEntity> dbSet;

        public Repository(BookStoreDbContext dbContext)        {            this.dbContext = dbContext;            this.dbSet = dbContext.Set<TEntity>();        }        public void Insert(TEntity entity)        {            dbSet.Add(entity);        }        public void Update(TEntity entity)        {            dbSet.Attach(entity);            dbContext.Entry(entity).State = EntityState.Modified;        }        public void Delete(TEntity entity)        {            if (dbContext.Entry(entity).State == EntityState.Detached)            {                dbSet.Attach(entity);            }            dbSet.Remove(entity);        }    }}

Repository类是对普遍业务操作泛型实现的地方,主要是对数据库的修改查询操作。下面的UnitOfWork 和IUnitOfWork也属于Infrastructure,这两个是用于对数据的保存。Repository和UnitOfWork都使用DbContext来对数据库进行操作,所以都有一个DbContext的字段。

public interface IUnitOfWork : IDisposable    {        DbContext Context { get; }        void Save();        bool IsDisposed { get; }    }

 /// <summary>    /// 用于对数据的保存操作    /// </summary>    public class UnitOfWork : IUnitOfWork    {        private  readonly BookStoreDbContext _context;        public DbContext Context        {            get { return _context; }        }

        public event EventHandler Disposed;

        public bool IsDisposed { get; private set; }        public void Dispose()        {            Dispose(true);        }        public virtual void Dispose(bool disposing)        {            lock (this)            {                if (disposing && !IsDisposed)                {                    _context.Dispose();                    var evt = Disposed;                    if (evt != null) evt(this, EventArgs.Empty);                    Disposed = null;                    IsDisposed = true;                    GC.SuppressFinalize(this);                }            }        }

        public UnitOfWork(BookStoreDbContext context)        {            _context = context;        }

        public void Save()        {            _context.SaveChanges();        }

        ~UnitOfWork()        {            Dispose(false);        }    }

到现在Repository模式的框架已经搭建好了,下面使用Book实体来完成一个具体的业务操作,对其他实体的操作都是下面一样的步骤。

8.1:添加实体

在MyRepository.Domain.Models文件夹下面添加一个实体类Book。

[Table("Book")]    public class Book    {        public int Id { get; set; }

        public string ISBN { get; set; }

        public string Title { get; set; }

        public string Type { get; set; }    }

8.2:修改DbContext

然后修改我们的DbContext类中添加一个DbSet属性,这样EF会在数据库中添加Book表。

 public class BookStoreDbContext : DbContext    {        //EF从配置文件中寻找name=BookStore的数据库链接。        //如果不指定: base("BookStore"),则寻找name=BookStoreDbContext的数据库连接        public BookStoreDbContext()            : base("BookStore")        {

        }

        public DbSet<Book> BookCollection { get; set; }    }

8.3:添加IXXXRepository接口

在Repository类图中,只介绍了IRepoitory和Repository两个公共的类,而IXXXRepository和XXXRepository是具体使用时添加的类。下面在MyRepository.Domain文件夹下面添加一个IBookRepository,这个接口是对现有Book实体业务的扩展。可以看出该接口包含的操作种类多于IRepository接口。

    public interface IBookRepository : IRepository<Book>    {        //其他业务操作,在控制器中一般使用的是该接口        IList<Book> GetAllBooks();    }

8.4:实现BookRepository

在MyRepository.DAL.Repository目录下面添加一个BookRepository类。

 public class BookRepository : Repository<Book>, IBookRepository    {        //在执行子类构造函数之前,先执行基类Repository<Book>的构造函数        public BookRepository(BookStoreDbContext dbcontext)            : base(dbcontext)        {        }

        public IList<Book> GetAllBooks()        {            var list = dbContext.BookCollection;            return list.OrderBy(x => x.ISBN).ToList();        }    }

BookRepository类继承了对Book实体的所有业务操作,公共的操作在Repository<Book>中。因为BookRepository继承自Repository<Book>,而Repository<TEntity>继承并实现了IRepository<TEntity>,所以BookRepository不需要再次实现IRepository<TEntity>接口定义的方法,如果需要可以覆盖Repository<Book>的公共操作。

IBookRepository中定义了BookRepository的特有业务操作,在BookRepository必须给予实现。IBookRepository必须继承自IRepository,这样在控制器中使用IBookRepository能够包含BookRepository的所有操作。在控制器结合IOC时IBookRepository能够很好的引用BookRepository对象。

其实在企业项目中,BookRepository与MyRepository.Web中的C与V操作是不同步的。就是说不是在BookRepository完成后就立刻去写BookController,在一个控制器中可能会包含多个IXXXRepository接口类型的属性,在构造时接收XXXRepository对象。但是在这里我直接写一个简单的BookController并且不使用IOC,来简单介绍Repository模式。

9

在MyRepository.Web.Controllers中添加一个控制器MyRepository.Web.BookController

public class BookController : Controller    {        private IBookRepository bookRepository;        private IUnitOfWork unitOfWork;

        public BookController()        {            BookStoreDbContext bookStoreDbContext = new BookStoreDbContext();             bookRepository = new BookRepository(bookStoreDbContext);            unitOfWork = new UnitOfWork(bookStoreDbContext);        }

        public ViewResult List()        {            IList<Book> listBook = bookRepository.GetAllBooks();            return View(listBook);        }

        [HttpGet]        public ViewResult Create()        {            return View();        }

        [HttpPost]        public ActionResult Create(Book book)        {            bookRepository.Insert(book);            unitOfWork.Save();            return RedirectToAction("List");        }    }

对于View的添加,路由的设置属于MVC3的内容:http://www.bbsmvc.com/mvclearn/thread-173-1-1.html。在MVC3这本书中还提到IOC也可以结合该列子。下面是数据库和运行效果。

 

http://www.cnblogs.com/zhongxinWang/archive/2012/02/22/2360283.html

时间: 2024-10-11 14:06:50

MVC中的Repository模式的相关文章

MVC单元测试,使用Repository模式、Ninject、Moq

本篇使用Repository设计MVC项目,使用Ninject作为DI容器,借助Moq进行单元测试. 模型和EF上下文 模型很简单: public class Foo { public int Id { get; set; } public string Name { get; set; } } EF上下文为: using System.Data.Entity; namespace MvcApplication1.Models { public class FooBarContext : DbC

4.CRUD Operations Using the Repository Pattern in MVC【在MVC中使用仓储模式进行增删查改】

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 上一篇文章,讲到了MVC中基本的增删查改,这篇文章,我会继续说到,使用仓储模式,进行增删查改. 什么是仓储模式呢,我们先来了解一下:  仓储模式是为了在程序的数据访问层和业务逻辑层之间创建一个抽象层,它是一种数据访问模式,提供了一种更松散耦合的数据访问方法.我们把创建数据访问的逻辑代码写在单独的类中,或者类库中

6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

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

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-uni/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

细说MVC中仓储模式的应用

文章提纲 概述要点 理论基础 详细步骤 总结 概述要点 设计模式的产生,就是在对开发过程进行不断的抽象. 我们先看一下之前访问数据的典型过程. 在Controller中定义一个Context, 例如: private AccountContext db = new AccountContext(); 在Action中访问,例如获取用户列表: var users=db.SysUsers; 类似于这种,耦合性太高.业务逻辑直接访问数据存储层会导致一些问题,如 重复代码:不容易集中使用数据相关策略,例

仓储模式在MVC中的应用学习系列

好久没写博客了,学习的东西,还是需要记录下来,自己懂还得懂得表达出来,这才是最重要的.好了废话说多了,现在开始正题.     在这个系列中,我会把仓储模式和工作单元在MVC应用程序中的应用写出来.有不对的地方,欢迎大家指正. 目录 1.仓储模式在MVC应用程序中的使用 2.泛型仓储模式在MVC应用程序中的使用 3.MVC Code-First和仓储模式的应用 4.待续....

MVC模式和Django中的MVT模式

MVC模式:是一种程序设计模式,其核心思想是分工.解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容. MVC:Model-View-Control M:主要封装对数据库层的访问,对数据库中的数据进行增删查改的操作. V:用于封装结果,生成页面展示的html内容. C:用于接收请求,处理业务逻辑,与Model和View交互,返回结果. MVC模式8步走: 1.客户端(浏览器.Ajax.app.爬虫程序)发送请求到服务器 2.服务器control(接收请求,业务处理,返回

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

大家久等了. 本篇专题主要讲述MVC中的权限方案. 权限控制是每个系统都必须解决的问题,也是园子里讨论最多的专题之一. 前面的系列文章中我们用到了 SysUser, SysRole, SysUserRole 这几个示例表. 我们以此为基础,完成RBAC (基于角色的控制) 的核心功能. 在此给出我的最佳实践,最终的效果是针对任意一个Action或Controller,都可以根据配置的角色来控制访问权限. 完成此核心功能后,可以再往两方面扩展常用功能: 1. 可以根据 组织/用户/角色 的并集来控

Repository模式

近来发现很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近发布的免费的ASP.NET MVC教程都使用了该模式.就简单看了下. 在<企业架构模式>中,译者将Repository翻译为资源库.给出如下说明:通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调. 在<领域驱动设计:软件核心复杂性应对之道>中,译者将Repository翻译为仓储,给出如下说明:一种用来封装存储,读取和查找行为的机制,它模拟了一个对象