C# 实体框架与存储库模式
我想知道存储库模式在使用实体框架的项目中的有用性。关于这一点有相反的说法——有人说EF是存储库和工作单元模式本身的实现,所以不需要将其封装在下一个抽象层中,有人认为它具有分离DAL和BL以及更容易创建单元测试等优点。根据我的经验,我经常遇到以下方法(通常,不仅在EF项目中): 据我所知,服务不应该有任何DAL操作——这意味着我们不应该从存储库返回IQueryable集合,因为这样查询将在存储库之外执行,单元测试将不完全可靠(LINQ到实体和LINQ到对象之间的差异) 我在这里看到了查询效率的问题——我们通常会从数据库中获取比需要更多的数据,然后在内存中进行过滤C# 实体框架与存储库模式,c#,entity-framework,C#,Entity Framework,我想知道存储库模式在使用实体框架的项目中的有用性。关于这一点有相反的说法——有人说EF是存储库和工作单元模式本身的实现,所以不需要将其封装在下一个抽象层中,有人认为它具有分离DAL和BL以及更容易创建单元测试等优点。根据我的经验,我经常遇到以下方法(通常,不仅在EF项目中): 据我所知,服务不应该有任何DAL操作——这意味着我们不应该从存储库返回IQueryable集合,因为这样查询将在存储库之外执行,单元测试将不完全可靠(LINQ到实体和LINQ到对象之间的差异) 我在这里看到了查询效率的问题
例如,让我们考虑<强> BooValuyPosiple(String登录,String密码)方法。 在这种情况下,我们需要从数据库中获取整个用户实体,例如,它可以有50个属性,仅用于密码验证。当然,我们可以在存储库中创建许多方法,如:
string GetPasswordHash(string login)
或
不需要从数据库获取整个实体,但在我看来,这可能是一个“小”开销
我们还可以将VerifyPassword功能从服务移动到存储库,然后我们应该问自己是否需要两层——存储库和服务。但如果我们合并它们,我们将失去分离DAL和BL层的好处——单元测试实际上就是集成测试。所以,也许将其全部保存在控制器中并注入模拟的DbContext或使用类似于单元测试的努力会更简单(更好)
我将非常感谢您的回答,您如何看待这一点,以及您如何在项目中解决这一问题
更新
我知道存储库模式允许轻松地将数据源/提供者更改为其他类型,如nHibernate、LINQ转换为SQL、普通ADO等
但您能告诉我如何在存储库API中实现排序和分页吗?我的意思是,将排序和分页规范传递给存储库的最佳方式是什么?我看到一些传递LINQ的函数谓词,但这将使存储库与LINQ紧密耦合—将其与普通ADO、存储过程等一起使用会有问题。在我看来,创建许多方法,如GetUsersOrderedByNameDesc()等是疯狂的。所以,也许可以为规范创建自己的类,伪造并传递排序/分页标准,并在存储库中处理它?如果是,你能给我一些实施的例子吗?我将尝试回答你的核心问题。这是我的两分钱。 为什么是存储库与实体框架。在设计或选择哪一个时,您需要回答我建议您提出的一些问题:
我不确定实际的问题是什么,所以这是一个评论,而不是让你更具体的答案。当然,拥有存储库层和独立的服务层是个好主意。上面提到的VerifyPassword是一种很好的服务方法,它只需要用存储库语言而不是DAL语言来实现。我不同意这一点,但这没关系。它只是表明这个问题对于StackOverflow的问答格式来说太宽泛了。
public interface IUsersRepository
{
IEnumerable<User> GetAll();
User Get(int id);
User GetByLogin(string login);
void Update(User item);
void Delete(int id);
void Delete(User item);
// ...
}
public interface IUsersService
{
// ...
bool VerifyPassword(string login, string password);
void ChangePassword(string login, string password);
// ...
}
string GetPasswordHash(string login)
bool VerifyPassword(string login, string passwordHash)
{
return db.Users.Any(x => x.Login = login && x.Password = passwordHash);
}