【问题标题】:A repository, according to the Repository pattern, should provide queries or actual entities?根据存储库模式,存储库应该提供查询还是实际实体?
【发布时间】:2011-04-12 08:59:59
【问题描述】:

我目前正在重构使用 ASP.NET MVC3 与 C# 和 Razor 开发的 Web 应用程序的代码。为了更好地构建我的应用程序,我使用的一种模式是Repository pattern,它除了是一个非常有用的模式之外,也是开发人员社区中经常讨论的问题。

在这种情况下,我发现Fredrik Normen 的一篇文章指出,根据 Repository 的定义,存储库类必须提供实际实体(例如 .NET 中的 List)而不是可查询对象(.NET 中的 IQueriable) .相反,在来自 ASP.NET MVC 官方网站的NerdDinner tutorial 中,当存储库必须提供同一对象的多个实例时,他们使用 IQueriable,而当存储库必须提供对象的单个实例时,它们使用实际实体。

根据存储库模式对存储库类/接口进行建模时,最正确的方法是什么?

谢谢

弗朗西斯科

【问题讨论】:

标签: c# asp.net design-patterns repository-pattern


【解决方案1】:

在我看来这种事情不利于你的时间利用。 ;-)

理论上,您的存储库应该返回对象或它们的传统集合,是的。但是,即使您链接到的存储库模式的定义也使用术语“类似集合的接口”。当然,IQueryable<Entity> 是一个“类似收藏”的界面,是吗?

在实践中,我几乎从不考虑区别......但我总是尝试将所有查询代码放在存储库中。我会说我 90% 的基于集合的存储库方法返回传统集合,而另外 10% 的返回基于 IQueryable<> 的东西。异常通常与分页有关。所以我可以从查询中获取总数如果需要,如果我不需要它,则不必提前获取该信息。这有点懒,但对我有用。

但我确实认为总是尝试返回传统集合是一个好主意,因为这意味着您将所有查询封装在存储库中,这应该是它应该在的地方。我建议不要太拘泥于极端水平,即坚持某人对 Pattern-X 的要求是什么

【讨论】:

  • 感谢您的回答。我同意在开发的第一阶段,您更关心使您的应用程序正常运行,并且在存储库之外进行一些查询更方便。但是,当您重构时,您总是会尝试遵循可以提高应用程序质量的准则和模式。目前我的应用程序使用数据库来存储/获取数据,但将来将使用 Web 服务。我想知道在上面列出的两者之间最方便的存储库方法,这将减少这种“替换”的工作量。谢谢
  • 实际上根本没有“差异”。我记得,Nerd Dinner 应用程序不会在存储库之外进行查询。如果是这样,它可能只是说明了其他一点。将您的查询代码保存在存储库中,是的;只是不要太担心返回的是哪种“类集合接口”的确切语义。但是,如果您喜欢更严格的要求,那么您会做得很好。
【解决方案2】:

正如您已经发现的那样,对此会有不同的看法。对于小型应用程序,让您的存储库公开 IQueryable 可能是可以的。

您当然不应该做的一件事是将 IQueryable 传递给您的视图。确保您的视图只接收物化对象和集合(如列表或数组)。 这样,如果某处的查询中存在错误,它将发生在控制器(或存储库)中,而不是您的视图中。这使您能够测试查询并优雅地处理错误。

【讨论】:

  • 为什么不传递给视图?有什么不同?这会减少抽象泄漏吗?
  • @Marnix van Valen:感谢您的回答。我总是强迫自己不要使用 ViewData 而是使用 ViewModels 来增强测试。我认为这是避免将 IQueriables 传递给视图的最佳方法。您能否具体说明一下您认为的“小规模应用”?谢谢
  • @Arnis IQueryable 可能会进行惰性求值,具体取决于下面的查询和存储。最坏的情况是它会在渲染视图时对你的数据库进行多次查询。那里有很多事情可能出错。您可能想阅读this article 了解更多信息。
  • @Francesco small scale 对我来说是一个快速而肮脏的应用程序,例如用于演示一些想法的概念证明。它也可能是一个我独自开发的应用程序,它永远不会离开我的公司。例如,我最近构建了一个小型迁移工具,用于将应用程序从一个版本升级到另一个版本。源代码将在下一个版本中从源代码树中删除。只要代码将由多个人编写或寿命超过几个月,我就会遵守规则,没有例外。
  • @Marnix 我的观点是——将IQueryable 暴露于服务/控制器层与进一步暴露于视图层有什么区别?我的意思是——在这两种情况下暴露这样的抽象都是不好的。
猜你喜欢
  • 2012-03-10
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 2018-06-02
  • 2014-06-04
  • 2015-02-21
  • 2010-12-11
相关资源
最近更新 更多