Entity framework 通用存储库和泄漏抽象
我正在实现一个存储库模式。我的主要原因是:Entity framework 通用存储库和泄漏抽象,entity-framework,entity-framework-5,repository-pattern,onion-architecture,leaky-abstraction,Entity Framework,Entity Framework 5,Repository Pattern,Onion Architecture,Leaky Abstraction,我正在实现一个存储库模式。我的主要原因是: 将客户端代码从持久性细节中抽象出来(实体框架) 支持可测试性 是否为通用存储库? 我遇到的问题是我是否应该拥有一个通用存储库。IQueryable Query()方法将为调用代码提供构造特定查询的方法。这里的问题是,这是一个漏洞百出的抽象——实体框架的细节现在正在泄漏到我的客户机代码中 这将如何影响单元测试?我是否仍然能够使用此实现模拟icCustomerRepository 这将如何影响我的持久层?比如Azure存储表或NHibernate
- 将客户端代码从持久性细节中抽象出来(实体框架)
- 支持可测试性
IQueryable Query()
方法将为调用代码提供构造特定查询的方法。这里的问题是,这是一个漏洞百出的抽象——实体框架的细节现在正在泄漏到我的客户机代码中
- 这将如何影响单元测试?我是否仍然能够使用此实现模拟
icCustomerRepository
- 这将如何影响我的持久层?比如Azure存储表或NHibernate
否则,我必须在
icCustomerRepository
上实现非常具体的查询方法,例如GetIsActiveByFirstName()
和GetIsActiveByDistrict()
。我非常不喜欢这一点,因为我的存储库类将被不同的查询方法挤满。这个系统有数百个模型,因此可能有数百个甚至数千个这样的方法需要编写和维护。通过坚持该模式,您可以拥有一个相对干净的i假设
数据访问层
- 参考EF和核心项目
- Has
Respository:iRespository
- 选项具有IEFJunk声明(仅当使用多个存储库时)
- 对核心的引用
- Respository被注入上下文(通常在实例化期间)
核心
- 可以“注入”的接口
- i推定声明。没有EF数据类型使用
- 未提及EF
因此,现在在核心代码中,您可以参考i假设。
实现类可以具有EF细节。但这不能从核心访问
这样你就可以有一个IQueryable了
public interface IRepositoryBase<TPoco>{
IQueryable<TPoco> GetListQ(Expression<Func<TPoco, bool>> predicate);
//...
公共接口IRepositoryBase{
IQueryable GetListQ(表达式谓词);
//...
但是如果你决定要添加
//...
// logically exposing IQueryable<T> Include<T>(this IQueryable<T> source, string path) from EF
IQueryable<TPoco> IncludeNAVProp(string navToInclude);
}
/。。。
//从EF逻辑公开IQueryable Include(此IQueryable源、字符串路径)
IQueryable IncludeNAVProp(字符串导航包含);
}
然后是存储库实现
return Context.Set<TPoco>().Include(navToInclude);
返回Context.Set().Include(navToInclude);
要求基础提供程序为EF。所以现在模拟是针对实际的EF提供者的
除非你小心,否则EF是特定的代码。泄露出去。
实际上,包含“include”概念的接口假设已经被认为是有漏洞的。
将EF细节排除在您的接口之外,是避免泄漏的关键。
而且您可以有1个IRepository
和1个Respository
并支持100个表相似:同样相似:感谢链接,但我对测试仍有点不清楚。为什么我不能用IQueryable来模拟?你可以用IQueryable来模拟/moq。。。Gert链接的点有链接,除非您对如何声明您的IREPOSITORY很认真,并且最终可能泄漏EF细节。Mocking-EF不是直截了当的,但是你应该声明为不负责任的域/核心层不应该引用EF。哦,我也写过Mocking。我忍不住。。。