让我们从总结这个问题的两句话开始:“包装 DbContext 是一个泄漏的抽象。无论如何,您最终会在服务/控制器层中对 EF 产生某种依赖。” 引用 ref 和第二个引用:
“DbContext 类
表示工作单元和存储库模式的组合,使您能够查询数据库并将更改组合在一起,然后将这些更改作为一个单元写回存储。” MSDN
请不要说存储库模式允许您简单地换出数据库,它不允许。有没有人用成熟的应用程序做到这一点?也请不要回答存储库模式不应该公开 IQueryable,我认为这只是另一种表示您不信任与您一起工作的人的方式。
我完全支持封装、代码覆盖率/可测试性,但由于这种流行的 EF 回购模式暴露了 IQueryable,因此不再需要这种模式:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(int id);
IEnumerable<T> Get(Expression<Func<T, bool>> filter = null,Func<IQueryable<T>,IOrderedQueryable<T>> orderBy = null, string includeProperties = "");
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(int id);
}
存储库模式与 UOW 模式相结合的唯一好处是: 1. 轻松启用依赖注入模式以提高可测试性/代码覆盖率 2. 封装外部集成存在的复杂性(对不同供应商的 Web 服务调用、Web API、数据库, ETC..)
那么我得到了什么封装,我没有通过使用 MyDbContext 得到什么:DbContext 类?我的 ORM 是抽象的 当然,我通过工作的 UOW 和常见的查询(如添加和删除)获得了一些控制器的一致性,但这真的值得付出努力。我不能只相信我的开发人员是统一的,当他们以自己的方式做事时,不要让强迫症。并且由于控制器可以编写它想要的任何查询,这难道不是面对单元测试吗?并且(甚至更大的上限大声笑)如果我要调用第三方 API,我可以在控制器的 MyDbContext 类中使其可访问,因此它看起来只是对控制器的另一个数据调用。
我再说一遍,为什么不直接使用 ORM,它是数据抽象!
以下是一些反对存储库模式的论据:
http://ayende.com/blog/3955/repository-is-the-new-singleton
http://lostechies.com/jimmybogard/2012/09/20/limiting-your-abstractions/
http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/
这是存储库模式的正确论据(虽然不够令人信服): http: //www.sapiensworks.com/blog/post/2012/10/10/Do-We-Need-The-Repository-Pattern.aspx