关于EF Unit of Work Repository的简单用法
2014-11-11 15:29
495 查看
其实ef本身就是unit of work+repository的
其中继承自DbContext的类就是unit of work
context中的DbSet<T>属性就是repository,你也可以不建那些属性,而使用context.Set<T>来获取一个DbSet<T>
如果直接在逻辑层就ef了,一来可能觉得会与ef绑的太紧,二来可能mock的难度会变大。所以有时候还是希望逻辑层引用的是自己定义的unit of work接口和repository接口
先来看这两个接口吧
……
建一个适配器类,构造的时候接收context和dbset
之后,我们要实现IRepository的方法
把他导向到dbset的方法去即可
因为,我们的IRepository是集成了IQueryable的,还得实现这些
统统导向到dbset的方法去
我们让context的方法返回这个适配器
使用是uow.GetRep<T>().Where(x=>x…….)各种where,first,count,any,只要是IQueryable支持的都可以正常使用
并且根据你IRepository中定义的方法,还可以add,delete之类的
但是有一个ef的方法在这里是不行的,那就是Include。
普通的where之类的方法,看源码
他是用source的provider去走。
这里,source是我们的IRepository,实际是RepositoryAdapter,adapter中的provider,我们返回的是dbset的provider,所以他可以正常的走到dbset去查库
但是,我们看include
include 并没有走provider,而是要看source是不是DbQuery<T>或者ObjectQuery<T>,我们这里自然都不是,所以include没能正确的导向到dbset的include去
我们可以自己写一个扩展方法
为了能访问到source的dbset,我们得把dbset用只读属性公开出来。
这样,我们就可以正确的把include也导向到dbset的include了。
如果你要换orm了,你需要为新的orm开发对应的适配器类
其中继承自DbContext的类就是unit of work
context中的DbSet<T>属性就是repository,你也可以不建那些属性,而使用context.Set<T>来获取一个DbSet<T>
如果直接在逻辑层就ef了,一来可能觉得会与ef绑的太紧,二来可能mock的难度会变大。所以有时候还是希望逻辑层引用的是自己定义的unit of work接口和repository接口
先来看这两个接口吧
public interface IUnitOfWork { IRepository<T> GetRep<T>() where T : class; int Comment(); } public interface IRepository<T> : IQueryable<T> where T : class { T Add(T obj); }
repository我只写了一个add方法做为说明,你可以写更多的方法
public class DatabaseContext : DbContext, IUnitOfWork { public IRepository<T> GetRep<T>() where T : class { return null; } public int Comment() { return this.SaveChanges(); } }
建一个ef的context,继承DbContext的同时,实现IUnitOfWork
其中的comment方法,直接调用ef的savechanges,其实要是偷懒,直接把接口里的comment命名成savechanges就完事
剩下就是得实现这个getrep<T>的方法了。
我们对外提供的是IRepository,而我们有的是ef的DbSet,俩边接口不匹配,祭出适配器模式。
public class RepositoryAdapter<T> : IRepository<T> where T : class { private DbContext context; private IDbSet<T> set; public RepositoryAdapter(DbContext context, IDbSet<T> set) { this.context = context; this.set = set; }
……
建一个适配器类,构造的时候接收context和dbset
之后,我们要实现IRepository的方法
public T Add(T obj) { return set.Add(obj); }
把他导向到dbset的方法去即可
因为,我们的IRepository是集成了IQueryable的,还得实现这些
public IEnumerator<T> GetEnumerator() { return set.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public Expression Expression { get { return set.Expression; } } public Type ElementType { get { return set.ElementType; } } public IQueryProvider Provider { get { return set.Provider; } }
统统导向到dbset的方法去
我们让context的方法返回这个适配器
public IRepository<T> GetRep<T>() where T : class { return new RepositoryAdapter<T>(this, this.Set<T>()); }
使用是uow.GetRep<T>().Where(x=>x…….)各种where,first,count,any,只要是IQueryable支持的都可以正常使用
并且根据你IRepository中定义的方法,还可以add,delete之类的
但是有一个ef的方法在这里是不行的,那就是Include。
普通的where之类的方法,看源码
他是用source的provider去走。
这里,source是我们的IRepository,实际是RepositoryAdapter,adapter中的provider,我们返回的是dbset的provider,所以他可以正常的走到dbset去查库
但是,我们看include
include 并没有走provider,而是要看source是不是DbQuery<T>或者ObjectQuery<T>,我们这里自然都不是,所以include没能正确的导向到dbset的include去
我们可以自己写一个扩展方法
public static IQueryable<T> Include<T>(this IRepository<T> source, string path) where T : class { var s = source as RepositoryAdapter<T>; if (s != null) { return s.Set.Include(path); } return source; }
为了能访问到source的dbset,我们得把dbset用只读属性公开出来。
这样,我们就可以正确的把include也导向到dbset的include了。
如果你要换orm了,你需要为新的orm开发对应的适配器类
相关文章推荐
- MVC+MEF+UnitOfWork+EF架构,网站速度慢的原因总结!(附加ANTS Memory Profiler简单用法)
- MVC+UnitOfWork+Repository+EF 之我见
- MVC+UnitOfWork+Repository+EF 之我见
- MVC+UnitOfWork+Repository+EF
- EntityFramework用法探索(四)Repository和UnitOfWork
- ASP.NET MVC3.0+ JqGrid+Unit Of Work+ Repository/ EF 4.1 CRUD应用 (多层结构)
- MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目
- Using Repository and Unit of Work patterns with Entity Framework 4.0
- 【无私分享:ASP.NET CORE 项目实战(第五章)】Repository仓储 UnitofWork
- Repository仓储 UnitofWork
- EF Unit Of Work
- Revisiting the Repository and Unit of Work Patterns with Entity Framework
- .NET MVC4 实训记录之四(Unit of work + Repository)
- 基于NHibernate的UnitOfWork+Repository模式(AutoFac)
- 基于NHibernate的UnitOfWork+Repository模式(AutoFac)–Part2
- 【无私分享:ASP.NET CORE 项目实战(第五章)】Repository仓储 UnitofWork
- MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目
- Unit of work + Repository
- 基于NHibernate的UnitOfWork+Repository模式(AutoFac)–Part1
- EF 4.1+MVC3+Jquery Ajax+Json.Net+JqueryUI+IUnitOfWork+Repository 学习DEMO(暂停更新)