存储库设计模式

时间:2011-03-02 11:34:32

标签: design-patterns repository-pattern

我见过许多存储库模式实现。特别是2种类型

  1. 它们公开了可查询的通用存储库,并期望服务类中的lamba表达式从数据库中获取数据。

  2. 编写方法,根据业务需求从数据库中获取数据,并封装检索数据的逻辑(甚至是lambda)。

  3. 哪一个是更好的方法?

2 个答案:

答案 0 :(得分:13)

我真的更喜欢第二个。

即使我看过.NET世界顶级博主的文章,对我来说,可查询对象在存储库中也是邪恶的。

原因:

  1. 存储库就像一个对象集合,但存储在其实现定义的任何位置。

  2. 存储库抽象数据映射到对象的方式。数据存储可以是任何东西,但是业务依赖于存储库来检索,添加,更新或删除域对象。

  3. 对底层商店的任何读或写访问权限必须由存储库本身或任何其他底层层管理。

  4. 可查询会破坏大部分这些点和/或原因。

    例如,为什么要设计 GetProductByName GetProductByCode ,如果可以使用IQueryable上的LINQ进行设置?

    并且在n层方案中,Queryable工作正常,因为您将无法访问另一层中的数据库连接,而不是返回延迟集的数据库连接。

    我不认为“可查询”的概念和存储库应该适用于任何软件设计,因为它告诉存储库是无用的。

    Queryable就像设计一个 GetAll 方法。存储库中GetAll的重点是什么?存储库将检索所有域对象,您将在业务中过滤它们。但是......等等......存储库不应该用某些标准检索域对象,是吗?

    虽然我发现可查询与存储库不兼容,但设计和实现一些接受lambda表达式或任何委托的存储库方法,以便为我提供某种过滤器或行为,这很好。这不是延期执行,而是委托。

答案 1 :(得分:1)

我更喜欢第一个。

可查询版本更好,因为它需要更少的代码并且更灵活

您无需事先知道您在寻找什么。

  // instead of repository.FindByMinimumAge(18)
  customerList = repository.Find<Customer>(c => c.Age >= 18)

使用第二种方法,您的Repository-Interface必须包含方法FindByMinimumAge(int minimumAge)(以及methodFindByName和方法....)

<强>更新

存储库界面如下所示。

public interface IRepository<T> where T : class
{
    IEnumerable<T> Find(Expression<Func<T, bool>> where);
    ...
}

这可以通过NHibernate,Linq2Sql或“使用arraylist模拟”来实现。