11

将数据库实体映射到模型和执行业务逻辑的最佳实践是什么?我已经看到了两者的相当不同的实现。我注意到许多实现,其中存储库(在数据层中)本身负责将数据库实体映射到域模型。例如,可以执行此操作的存储库:

public IQueryable<Person> GetPersons()
{
      return DbSet.Select(s => new Person
                    {
                        Id = s.Id,
                        FirstName= s.FirstName,
                        Surname= s.Surname,
                        Location = s.Location,
                    });
}

但是在对 SO on N Tier 设计进行全面搜索后,我注意到虽然没有灵丹妙药,但在大多数情况下,建议手动或使用 Mapper 在 MVC 项目中的控制器内部执行映射。还重申了服务层永远不应该执行映射,它的职责应该是执行业务逻辑。这里有几个问题:

  1. 关于将实体映射到模型的位置以及反之亦然,哪种方法是可取的?存储库应该这样做还是应该在控制器中完成映射?
  2. 假设我想对我从数据库中检索到的实体执行一些业务逻辑,例如返回实体的全名Person,或者将所有s的年龄增加Person10年,这个操作应该在哪里执行。在模型本身?例如,我会FullName在模型上有一个属性来计算全名和年龄吗?或者我是否在我的服务层中定义了一些服务来执行业务逻辑?

编辑

哇这么多接近的票。抱歉,我搜索的不够全面。我在这里提出的“在哪里执行业务逻辑”问题已经可以在 SO 和其他地方找到(尽管有时传达得有些神秘):

Stephen Walther 使用服务层进行验证

瘦控制器

SO上的另一个很棒但更通用的答案

我应该在哪里把我的控制器业务逻辑放在 MVC 中

服务是否将实体映射到视图模型

但是,我还没有找到解决映射问题的标准解决方案,我想我或许可以更雄辩地表达我的问题。所以普遍的共识似乎是业务逻辑进入服务层,将领域模型映射到视图模型应该发生在控制器/表示层。并且由于建议不要将您的数据库实体显示到数据层以外的任何层,因此建议您手动或通过诸如 Auto Mapper 之类的映射器将您的实体映射到数据层的域模型(这是我从阅读许多文章)。我的困惑源于应该将实体映射到域模型以及将域模型映射到视图模型的问题。然而,正如我之前提到的那样,我本可以更清楚地表达我的问题。

4

4 回答 4

4
  1. 关于将实体映射到模型的位置以及反之亦然,哪种方法是可取的?存储库应该这样做还是应该在控制器中完成映射?

我强烈希望看到映射发生在存储库而不是控制器中。正如 Suhas 在他的回答中提到的那样,控制器需要纯粹充当协调员。作为替代方案,也许您可​​以利用存储库中的映射类来传递实体并返回映射模型 - 有点像Auto Mapper

  1. 假设我想对从数据库中检索到的实体执行一些业务逻辑,例如,返回 Person 实体的全名,或者将所有 Person 的年龄增加 10 年,应该在哪里执行此操作。在模型本身?例如,我会在模型上有一个 FullName 属性来计算全名和年龄吗?或者我是否在我的服务层中定义了一些服务来执行业务逻辑?

如果可能,请在服务上执行业务逻辑。为什么要让应用程序承担服务层应该做的事情?我相信这是服务的域,而不是应用程序的域。另外,我也不认为从模型返回连接或派生的属性是一件坏事。

概括:

  • 控制器处理来自视图的请求并将它们转发到存储库
  • 存储库是您的数据存储的管道
  • 服务处理来自存储库的请求,处理业务逻辑,并返回映射模型
于 2013-01-09T15:40:50.387 回答
1

我通常在 MVC 项目中创建一个小型服务层来处理 MVC 层需要完成的额外工作。因此,在您的示例中,您可以使用 aPersonService或 aPersonHandler调用业务层以获取所有人员实体,然后将所有人的年龄增加 10 年(假设这不是您的业务逻辑,而只是 UI 需要的东西),连接名字和姓氏以构建全名等。控制器然后只是调用此服务并且永远不知道幕后发生了什么。这样你的控制器就在做它应该做的事情——在视图和模型之间进行协调。

于 2013-01-09T13:12:52.573 回答
1

这取决于...就像你说的没有灵丹妙药。只能列出每种方法的优缺点,但仍然是您比这里的任何人都更了解您的需求。如果你有时间,我建议阅读这本书企业应用架构模式。这将使您对不同的业务逻辑和数据源架构模式、何时以及如何使用它们有一个很好的理解。什么应该去业务层,什么应该去 DAL。本书还解决了如何从 DAL 映射到域实体的问题。从长远来看,您甚至可能改变主意并选择完全不同的方法。

还可以考虑使用一些 ORM,它为您提供代码优先机制,如 EF Code First 或 NHibernate。在这种情况下,所有映射逻辑对您来说都是透明的。

于 2013-01-09T16:03:49.750 回答
1

数据访问层(存储库)应该只处理插入/更新/检索您的数据实体。您的服务层处理业务逻辑并负责表示层(控制器、视图模型)和数据层之间的通信。这意味着您从数据实体到域的转换应该发生在这一层。您的表示层(控制器)应该处理您的视图模型和域模型之间的转换。-如果你想有更好的理解,你应该接受 Maksym 的建议和拾取企业应用程序架构模式,因为我认为(和许多其他人)认为 Fowler 是 Web 应用程序开发的权威。另一本好书是 ASP.NET Design Patterns,它基于 Fowler 的书,但只关注 ASP.NET 框架。

于 2013-04-09T22:11:42.733 回答