在我的项目中,我使用的是EF Code First方法。我有一个存储库层,服务层和表示层(ASP.NET MVC)。我为每个视图使用专用视图模型。
我感到困惑的是,我的服务应该将实体返回到控制器以将它们映射到视图模型,还是应该实现 DTO 并从服务返回它们?
所以问题是,当流类似于"EF ->存储库 ->服务 -> UI"时,数据转换将是什么。 "实体 -> DTO ->视图模型"还是"实体 ->视图模型"?
似乎如果我使用 DTO,它们会有点重复实体。
我正在尝试遵循最佳实践。
使用 DTO 方法。
这将极大地帮助您保持应用程序独立于数据库结构更改。
将 EF 实体向上映射到表示层将使任何数据库更改都难以维护。您需要关注的地方太多了。
作为不同 proache 的两个示例:现在,我正在处理一个最初直接绑定到 EF 实体的大型项目。这会导致各种并发症。有些部分需要大量代码更改才能进行较小的数据库调整。另一方面,在我的家庭宠物项目中,我能够毫无困难地更改整个数据库系统 3 次,因为我之间有很好的抽象层。
特别是现在在开始时,您的项目架构仍然干净,实现 DTO 的工作似乎是重复的。但是,当您的几个应用程序层开始自己的生活时,这可能会随着时间的推移而改变。
如果您害怕实现 DTO 的看似重复的工作,那么像 AutoMapper 这样的映射库可以减轻您的很多痛苦。
这很难说,因为这完全取决于您的应用程序及其复杂性。如果你有很多转换,我会说使用DTO,如果不是简单地从实体到ViewModel。
一般来说,我会从尽可能少的转换开始。当事情变得复杂时,您仍然可以在两者之间添加另一层。请记住,添加抽象层比删除抽象层更容易。
MVC(以及几乎所有其他方法)的最佳方法是执行EF -> DTO -> ViewModel -> View。
切勿将 EF 用作绑定到视图的实体。 你会搬起石头砸自己的脚,但也违背了MVC的目的 - 你的模型部分。
因此,请创建EF,然后创建绑定到视图的模型。 是的,看起来像重复的工作,但实际上,它不是 - 它为您提供了更精细的控制,可以在视图中显示或包含的内容。
在一个理想的世界中,一切都是分开的,没有耦合。然而,在现实世界中,这并不总是务实的。
以你的方案为例,除非你使用的是 N 层体系结构(你似乎不是,更像是分层的体系结构),或者你的服务只对来自实体的非常有限的数据感兴趣,否则我会说 DTO 是过度杀伤力。与 EF 生成的代理实体相比,CodeFirst 实体非常轻量级,因此没有必要引入 DTO 以将相同的信息传输到另一层。
就个人而言,我会让我的实体实现一个通用接口,然后我用它来从我的服务层返回。这意味着您的服务有效地与您的 DAL 相关联(我想这不是那么好),但在您的情况下,它会完成这项工作。这使您可以灵活地在以后改变主意时稍后在服务层中换出实际的 DTO。