【问题标题】:How to access EF class properties from Service Layer如何从服务层访问 EF 类属性
【发布时间】:2012-02-20 11:44:35
【问题描述】:

我有一个用 C# 和 Razor 编写的 ASP.NET MVC3。应用的架构分为数据访问层(EF类+Repository)、服务层、控制器、ViewModels和View。

从我的服务层 ProductServices 我调用我的存储库 ProductRepository 公开的方法 GetAllProducts ,它具有以下签名:

IQueryable<Products> GetAllProducts()

因此在ProductServices 内我调用(productRepositoryProductRepository 的一个实例):

var products = productRepository.GetAllProducts(); 

填充变量products。现在我想从productServices 访问产品名称ProductName。如果我使用这条指令:

var productNames = products.Select(m => m.ProductName).ToList();

我正在创建 ServiceLayerEF 之间的耦合(绕过存储库)。这意味着我必须向ProductRepository 添加一个带有签名的方法:

IQueryable<string> GetAllProductsName()

但是,由于我的应用程序中需要其他产品信息,我是否应该在productRepository 中为Product 类的每个字段创建一个方法?我的推理正确吗?谢谢

【问题讨论】:

  • 如果它只是代理请求,你为什么需要服务层?
  • 感谢您的回答。当然我的服务层也有所有的业务逻辑和几个方法,这就是我需要它的原因
  • 是什么让你觉得这种耦合方式不好?
  • 因为我已经提前知道,一年后数据库将被另一个数据库取代。这意味着字段的名称最有可能被更改,我也应该在我的存储库中更改它们,如果发生耦合,也应该在我的服务层中进行更改

标签: c# asp.net-mvc-3 repository service-layer coupling


【解决方案1】:

围绕这一点有两种思想流派,

  1. 存储库明确定义了您与数据库交互的方式,并且应该受到严格控制。因此,存储库上的方法应提供枚举数据
  2. 存储库打破了与特定数据源类型的强耦合,但不需要提供详细的枚举数据集。

我个人订阅了第二个,原因如下:

我的感觉是,当您在存储库中过于明确时,它会变成业务逻辑而不是解耦机制。我不太喜欢这样,因为这意味着您与存储库实现的联系更加紧密。

我还认为,在某些情况下,存储库不是枚举数据的正确位置,例如,我认为分页和排序是 UI 问题,但是对于性能而言,您希望查询仅与当前页面/排序相关。这意味着您要么需要让 UI 参与查询编译,要么存储库需要了解分页和排序。

话虽如此,提供未枚举的数据源确实会让您在以后遇到问题,即使您确实提供了它们,尽快枚举数据集也非常重要。

如果你有兴趣,这里是我对存储库的看法:http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html,所有代码也在 github 上

【讨论】:

  • 感谢您的回答。因此,您建议我不要创建特定方法并通过服务层访问该字段,绕过存储库?
  • 我的感觉是,通过直接访问可查询对象,您实际上并没有绕过存储库,而是在进行运行时扩展。所以是的,在您从存储库中取回集合后,我可以使用选择。这里还需要注意的是,select 实际上是 LINQ 的函数,而不是 EF 或您的存储库的函数,它也很乐意在枚举集上工作。
  • 如果我事先知道数据库(以及随之而来的 EF)将被替换?如果我仅从 productRepository 访问字段,我必须只更改该层
  • 是的,当然改变层不应该是一个问题,唯一的问题是,如果你使用的新 ORM 不支持将 linq 编译为 SQL,你的存储库方法可能会因为查询而执行得慢一点会拉回更多的东西。
【解决方案2】:

您在 productServices 中拥有所有信息,因为您使用 productRepository.GetAllProducts() 方法从存储库加载所有信息。如果您需要来自其他实体的更多信息,则需要使用新服务扩展您的 productServices。

但是,由于我的应用程序中需要其他产品信息, 我应该在 productRepository 中为每个字段创建一个方法吗 产品等级?我的推理正确吗?谢谢

在这种情况下,我通常为服务创建扩展方法,而不是在存储库中。存储库通常有一个 CRUD 设置,仅此而已。

【讨论】:

  • 谢谢,这意味着您可以直接访问服务层中的字段,对吧?当然除了GetAllProducts我还有其他方法我没有在这里列出,因为它们不在问题的范围内
  • 在这种情况下是的。如果您在其他应用程序或数据库上下文(例如 WPF 应用程序或移动应用程序)中需要此逻辑,您永远不会。使用您的服务架构,您可以很好地处理这种情况。
猜你喜欢
  • 1970-01-01
  • 2020-09-06
  • 2016-10-11
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 2013-10-30
相关资源
最近更新 更多