似乎我找到了存储库模式的每个例子,实现在某种程度上是不同的。 以下是我主要找到的两个例子。

interface IProductRepository
{
    IQueryable<Product> FindAll();
}

然后通常有另一层与存储库通信并调用FindAll()方法并执行任何操作,例如查找以字母's'开头的产品或获取特定类别中的产品。

另一个例子我发现很多将所有的find方法都放入了存储库

interface IProductRepository
{
    IEnumerable<Product> GetProductsInCategory(int categoryId);
    IEnumerable<Product> GetProductsStartingWith(string letter);
    IEnumerable<PromoCode> GetProductPromoCodes(int productId);
}

你建议我选择哪条路? 或者彼此的优点/缺点是什么?

根据我的理解,阅读http://martinfowler.com/eaaCatalog/repository.html第一种方法似乎最能反映这一点?

===============>>#1 票数:16 已采纳

第一个是可怕的。 IQueryable就像一个GOD对象 很难找到100%完整的实现(即使在所有OR / Ms中)。 您可以直接公开ORM而不是使用它,因为否则您可能会得到泄漏的抽象层

乔尔说得最好(文字来自维基百科文章 ):

在Spolsky的文章中,他提到了许多关于抽象的例子,这些抽象在大多数时候都有效,但是底层复杂性的细节不容忽视,从而将复杂性推向了应该通过抽象本身简化的软件

Joels博客文章

第二种方法更容易实现,并保持抽象完整。

更新

您的存储库违反了单一责任原则,因为它有两个原因需要更改。 第一个是如果更改Products API,另一个是更改PromoCode API。 您应该使用两个不同的存储库,例如:

interface IProductRepository
{
    IEnumerable<Product> FindForCategory(int categoryId);
    IEnumerable<Product> FindAllStartingWith(string letter);
}

interface IPromoCodeRepository
{
    IEnumerable<PromoCode> FindForProduct(int productId);
}

换了东西:

  • 我倾向于在返回多个项目时使用Find开始方法,如果返回单个项目则Get
  • 更短的方法名称=更容易阅读。
  • 单一责任。 更容易分辨使用存储库的类对依赖项的影响。

小的定义好的接口可以更容易地发现违反SOLID原则的行为,因为类的中断原则往往会使得构造函数变得臃肿。

===============>>#2 票数:1

共识正在建立:第二种选择。 除了使用IQueryable泄漏遍布整个地方的查询逻辑之外,正确实现它的难度,测试和模拟非常困难。

===============>>#3 票数:0

我个人建议使用第二个例子,这样你就可以将搜索逻辑封装在一个地方,并且调用者的意图由他们调用的方法的名称明确定义。 如果您使用第一个示例,您的查询代码将在整个应用程序中泄漏,您将最终复制查询。

===============>>#4 票数:0

我建议避免重复。 这是第一个目标。 如果你有逻辑在几个地方找到以某个字母开头的产品,那么这是一个特例,它值得提取到单独的方法(它也为你的特定情况提供了很好的描述)。 没有重复的代码更容易更改,理解和维护。

所以,我倾向于使用一个使用IQueryable通用搜索方法和一组多次使用的方法:

interface IRepository<T>
{
    IQueryable<T> FindAll();
}

interface IProductRepository : IRepository<Product>
{
    IEnumerable<Product> GetProductsInCategory(int categoryId);
    IEnumerable<Product> GetProductsStartingWith(string letter);
    IEnumerable<PromoCode> GetProductPromoCodes(int productId);
}

还要考虑单元测试。 与IQueryable相比,特定方法更容易模拟。

===============>>#5 票数:0

我其实认为第一个更好。 我假设我决定以下因素:

  1. 如果产品结构将被重构:

    • IQueryable方法 - 您只需要在代码中更改调用方法。
    • IEnumerables - 您还需要更改方法名称。

  2. 如果有很多人要以多态方式派生您想要迭代的接口:

    • IQueryable方法 - 通用统一方法名称的好处
    • IEnumerables - 某些名称可能没有描述您需要的方法。

  3. Elasticness

    • IQueryable方法 - 易于划分为IEnumerables方法。
    • IEnumerables方法 - 很难转换回IQueryable方法。

因此,我建议您从IQueryable开始作为默认选择,随着代码的进展,您可以随时更改为您需要的更具体的IEnumerables方法。

  ask by Scott translate from so

未解决问题?本站智能推荐:

2回复

如何使用接口,基础和具体实现存储库模式

我几乎已经通过具有IRepository<T>接口, NewsRepository类和News实体来实现我的存储库模式。 我遇到的问题是试图将通用方法抽象为基本的Repository类。 我找不到在NewsRepository抽象Get方法的方法,因为它包含特定的Linq表达
4回复

存储库模式:模型关系的实现和延迟加载

我有一个处理产品和产品类别的应用程序。 对于每一个,我都有使用POCO定义的模型。 该应用程序使用存储库来访问这些模型 在Product类中,仅在需要/访问(延迟加载)时才应加载名为ProductCategory类型的Category属性。 我希望我的模型保持POCO并仅包含
4回复

使用RavenDB实现存储库和服务模式

我在RavenDB项目中实现存储库和服务模式有些困难。 主要关注的是我的存储库界面应该是什么样子,因为在RavenDB中我使用了几个索引来查询。 假设我需要获取parentid等于1的所有项目。一种方法是使用IQueryable List()并获取所有文档,然后添加where子句以选择p
2回复

实现存储库模式的正确方法是什么? 以及如何使用? [关闭]

我有一个名为Product的对象,我想从所有产品(存储在SQL Server中)的列表中检索某个产品的“物料清单”。 我应该首先创建Product对象,然后通过一种方法从存储库中获取数据,如下所示: 或从静态存储库检索数据海峡,如下所示: 或者也许是这样? 或者,也许当
4回复

使用旧的ado.net实现通用存储库模式

我试图使用ado.net实现存储库模式,因为平台有限。 如何完成以下抽象类......? 更新: 我将通过固有的这两个接口/类来实现域指定的存储库。
1回复

通过配置更改目标存储库实现的最佳模式

我对设计模式不是很有经验。 我正在使用asp.net core 2.0创建一个webapi应用程序。 我想实现一种设计模式,以便我可以配置是使用数据库存储库保存到sql数据库还是使用文件存储库保存到文件,否则我将使用消息传递服务作为消息发送到队列。 谁能建议我实现这一目标的最佳模式
1回复

使用存储库模式实现Web服务的正确方法是什么

我即将开始一个项目,该项目需要一个连接到Web服务的网站。 Web服务将从数据库中检索数据,并将其返回到网站。 我的问题是如何正确地将业务问题与数据访问分开。 可以使用存储库模式分离服务。 然后在服务调用实现中,我可以以实体的形式从存储库中获取所需的数据,然后通过线路返回它。
2回复

存储库和查询对象模式。 如何实现复杂的查询

我已经阅读了很多关于存储库模式的帖子,但是有一些实际问题似乎没有解决或解释。 这就是我对这两种模式的理解: 存储库和查询模式是互补的:查询对象表示业务逻辑(WHERE clausules),存储库模式具有Get(IPredicate)方法,该方法接受查询对象并返回SELECT WHERE
3回复

DI和存储库模式

目前,我的代码与此类似(缩短只是为了说明一点): DAL 存储库接口 基本EF存储库 基本存储库的示例实现 BLL 现在,一切都很好。 我可以简单地做这样的事情: 当我阅读这篇博文时,混乱开始,作者说使用如下代码: 是一种糟糕的技术,
2回复

ORM存储库模式

这是一个我正在寻找意见的问题。 我正在开发一个同时使用NHibernate和EntityFramework的项目(这是设计,需要灵活性)。 所以,我继续开始研究存储库模式,但遇到了一个轻微的困境。 基本上,我想知道你们对以下几个方面的看法: 存储库应该是单身人士吗? -