MVC+Repository+UOW+EntityFrmeWork的使用
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也可以结合该列子。下面是数据库和运行效果。


MVC+Repository+UOW+EntityFrmeWork的使用的更多相关文章
- mvc5 + ef6 + autofac搭建项目(repository+uow)(一)
		直奔主题了,不那么啰嗦. 整体框架的参考来源是 O# 的框架,在此感谢锋哥一直以来的开源,让我们有的学 如下图: (图一) 一下分三个步骤说明,分别为 dbContext,repository,uo ... 
- 关于ASP.NET MVC+Repository+Service架构的一些思考
		看了一些ASP.NET MVC开源项目后的一些想法,关于ASP.NET MVC+Repository+Service架构的一些思考 最近在学习ASP.NET MVC 2.0的一些开源项目,发现这些项目 ... 
- MVC Repository模式
		近来发现很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近发布的免费的ASP.NET MVC教程都使用了该模式.就简单看了下. 在<企业架构模 ... 
- 瞎折腾之 NHibernate ORM框架的接触(MVC + Repository源码)(一)
		在这炮火连天.技术更新迅猛的年代,不接触了解.甚至会用2~3种框架都不好意思说自己有多少年工作经验.况且出去面试也会有点吹牛的底子嘛. 这次折腾了NHibernate.其实这些ORM框架封装好了都是给 ... 
- spring mvc @Repository 注入不成功 的原因?
		这样的代码会影响 @Repository 注入 
- mvc5 + ef6 + autofac搭建项目(repository+uow)(二)
		续上篇: DBContext 在上篇 图一类库根目录创建的 DbContextBase /// <summary> /// 数据库上下文基类 /// </summary> // ... 
- Lind.DDD.UoW~方法回调完成原子化操作
		回到目录 本文来自于实践中的不足 在最近开始过程中,遇到了一个问题,之前设计的工作单元UoW只支持Insert,Update,Delete三种操作,即开发人员可以将以上三种操作同时扔进工作单元,由工作 ... 
- 我的那些年(9)~我来团队了,Mvc兴起了
		回到目录 我的那些年(9)~我来团队了,Mvc兴起了 在一次后出办事后直接去面试了 面试就是答卷子 六里桥一个好地址 搬回老家了 在老婆的建议下学驾照了 拿到大专毕业证了 买车了 愉一切可以愉的时间学 ... 
- application in 2014
		OA WEBSITE ERP ISO ANDROID EF+MVC4+CATCHE+JQuery+js+div+css+web性能优化+webservice+sql2008+设计模式+wcf+多线程 ... 
随机推荐
- PAT1008
			1008. Elevator (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B The highest building in our city has on ... 
- hdu_2255_奔小康赚大钱(KM带权二分匹配板子)
			题目连接:hdu_2255_奔小康赚大钱 存个板子 /* 其实在求最大 最小的时候只要用一个模板就行了, 把边的权值去相反数即可得到另外一个.求结果的时候再去 相反数即可,最大最小有一些地方不同.. ... 
- mysql 查看表的类型(转)
			MySQL 数据表主要支持六种类型 ,分别是:BDB.HEAP.ISAM.MERGE.MYISAM.InnoBDB. 这六种又分为两类,一类是”事务安全型”(transaction-safe),包括B ... 
- Vold工作流程分析学习
			一 Vold工作机制分析 vold进程:管理和控制Android平台外部存储设备,包括SD插拨.挂载.卸载.格式化等: vold进程接收来自内核的外部设备消息. Vold框架图如下: Vold接收来自 ... 
- SQL2005附加数据库时遇到的问题:用户组或角色在当前数据库已存在
			一次 附加备份数据库的 mdf 文件 成功后 创建登陆用户 但是 无法映射该用户的 对应数据库 出现 用户组或角色在当前数据库已存在 的问题 首先介绍一下sql server中“ ... 
- strut1.X和spring整合的二种方法
			第一种集成方法 原理:在Action中取得BeanFactory对象,然后通过BeanFactory获取业务逻辑对象 缺点:产生了依赖,spring的类在action中产生了依赖查找.(注意和依赖注入 ... 
- UIView 面面观
			原创:转载请注明出处 1.UIView: 一个视图对象控制该区域的渲染,同时也控制内容的交互. 2.UIView的功能就是:展示.渲染.交互 3.UIView 和很多其他视图控件的默认tag值是0,所 ... 
- android Service Activity三种交互方式(付源码)(转)
			android Service Activity三种交互方式(付源码) Android应用服务器OSBeanthread android Service Binder交互通信实例 最下边有源代码: ... 
- 深入浅出Ajax(一)
			客户端: <script type="text/javascript"> window.onload = initPage; function initPage() { ... 
- IGeoFeatureLayer
			Members All Properties Methods Inherited Non-inherited Description AnnotationProperties Annotation ... 
