2014-06-15 145 views
2

我想知道使用实体框架的项目中存储库模式的用处。对此有相反的说法 - 有人说EF是存储库和工作单元模式本身的实现,所以不需要将其包装在下一个抽象层中,有人认为它具有诸如DAL和BL分离以及更容易创建等优点的单元测试。根据我的经验,我经常遇到以下的方法(一般,不仅在EF项目):实体框架vs存储库模式

Repository (DAL) <-> Service (BL) <-> Controller 

Repository + Service + Type = Model 

Repository有只负责数据访问,即方法:

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); 
    // ... 
} 

据我了解,服务应该不会有什么DAL操作 - 这意味着我们不应该从即返回仓库IQueryable的集合,因为这样的查询将外库和单元测试执行不会是完全可靠的(之间的差异LINQ-to-Entities和LINQ-to-Objects)。

我在这里看到了查询效率的问题 - 我们通常会从数据库中获取比需要更多的数据,然后将其过滤到内存中。

例如,让我们考虑bool VerifyPassword(字符串登录,字符串密码)方法。

在这种情况下,我们需要从数据库中获取整个用户实体,例如,可以有50个属性,仅用于密码验证目的。我们当然可以,创建库许多方法,如:

string GetPasswordHash(string login) 

bool VerifyPassword(string login, string passwordHash) 
{ 
    return db.Users.Any(x => x.Login = login && x.Password = passwordHash); 
} 

,而不需要从数据库中获取完整的实体,但在我看来,这可能是一个“小”的开销。

我们也可以将VerifyPassword函数从服务移动到存储库 - 那么我们应该问自己一个问题,是否需要两个层 - 存储库和服务。但是如果我们合并它们,我们将失去分离DAL和BL层的益处 - 单元测试将是现实中的集成测试。所以也许它会更简单(更好)将它全部保存在控制器中,并注入模拟的DbContext或使用像Effort这样的单元测试?

我将非常感谢您的回答,您如何看待这一情况以及如何在您的项目中解决此问题。

UPDATE

我明白,存储库模式允许容易地改变像的nHibernate数据源/提供者以外,LINQ到SQL,平原ADO等。

但是你能告诉我你如何在你的仓库API中实现排序和分页吗?我的意思是将排序和分页规范传递给存储库的最佳方式是什么?我看到有些函数为LINQ函数使用了谓词,但是这会将存储库与LINQ紧密结合 - 使用它与纯ADO,存储过程等将会产生问题。创建像GetUsersOrderedByNameDesc()等许多方法在我看来是疯狂的。所以也许创建自己的规范类,伪造和传递排序/分页标准,并在库中处理它?如果是的话,你能给我提供一些实现的例子吗?

+1

我不确定实际问题是什么,所以这是一个评论,而不是让你更具体的答案。当然,这是一个不错的主意,它拥有存储库层和单独的服务层。提到的VerifyPassword是一个很好的服务方法的候选者,它只会在存储库语言而不是DAL语言中实现。 –

+0

我不同意,但没关系。它只是表明这个问题对于StackOverflow的Q&A格式来说太广泛了。 –

回答

0

我会尝试去尝试你的核心问题。这是我的两分钱。 为什么存储库vs实体框架。您将需要回答下面的一些问题,我建议您在设计或选择哪一个时问:

  1. 您的项目是否有可能有不同的存储库?如果是,那么存储库模式通过实体框架是有意义的。
  2. 拥有存储库模式还可以让您更容易地设置您的测试框架,您可以在存储库模式(DAL)将使用的模型数据库中进行设置。
  3. 您可能还想考虑对您的数据模型所做的更改可能会渗透到您的业务逻辑与实体框架的更改。