我应该将Entity(Persistent)对象转换为DTO对象吗?
我的项目是分层如下: -我应该将Entity(Persistent)对象转换为DTO对象吗?
DAL (Entity)
- >BLL (DTO)
- >ApplicationComponent (ViewModel)
。
将有多个应用程序组件(ApplicationComponent
),它将访问BLL
。组件包括Windows服务,Web服务,Web API和MVC控制器。
我正在转换NHibernate
Entity
对象到DTO
对象,同时将它们从DAL
传递到BLL
。在将此状态传递给ApplicationComponent
时,BLL
再次将其转换为ViewModel
。
这有助于我分离问题以及如何在每个层中处理数据。我不赞成恢复NHibernate
Entity
对象可以查看以下原因: -
- 数据获取暴露
UI
,我要隐藏(或仅在需要时暴露),如密码,用户类型,许可等 - 在引用/连接处,
NHibernate
在访问属性时会执行额外的查询,从而使使用延迟加载无效。 - 暴露给用户(
Entity
)的不必要的数据造成了错误的混淆和差距。 - 泄漏到
BLL
/UI
中的持久性实现。Entity
不适用于UI
。它在任何情况下都不能服务于UI
。 - 我们对
DTO
属性使用属性进行用户输入验证,这与Entity
看起来很奇怪。
我现在面临以下问题这种方法: -
- 最大的和明显的问题是相同的功能冗余的对象。
- 我必须在每个图层中编写映射器方法来转换对象。这可以通过使用
AutoMapper
或类似的东西来最小化;但并没有完全解决问题。
问题: -
- 这是过度分离,应该尽量避免(至少是最小化)?
- 如果这种方法是正确的,我没有看到任何简单的方法来完全绕过上述两个问题。请建议。
- 如果这种方法不正确,请提出更正建议。
参考: -
Link1建议转移
Entity
对象可以查看这在我的理解不是一个好主意。Link2建议映射
Entity
与DTO
我已经同意了。Link3没有帮助。
Link4建议使用类似自动映射工具的东西,这是可以的。但它仍然不能完全解决问题。
Link5是一个伟大的职位。它解释了为什么这些应该分开,我同意。它没有评论如何最小化由此引起的开销。
Link6再次没有帮助。
编辑1:
我刚才读this外观极好回答这表明使用Entity
这在UI
如果可能的话。它仍然不适用于我的大部分项目。
编辑2:
另一个优秀post建议去映射双向,因为我现在做的事情。它仍然没有提出一种最小化开销的方法。
案例1:DAL(实体) - > BLL(DTO):
NHibernate的需要声明我的实体的属性作为virtual
懒加载的情况。请参阅this和this。所以,我们可以假设NHibernate为实体做了一些事情(为延迟加载创建代理等),并且我们更好地嘲笑它。更好的是我们将实体转换为DTO。然后,我们可以以任何我们想要的方式使用DTO。当然,缺点是需要额外的编码和维护。
案例2:BLL(DTO) - > ApplicationComponent(视图模型)
正如我们已经断开NHibernate的(通过复制实体到DTO)以上,我们可以自由地重用DTO传递数据查看。所以,只要有可能,我们可以重用DTO。如果不可行,我们可以创建新的ViewModel并将其映射到DTO。
很多互联网上的帖子强烈建议为每个视图创建新的ViewModel。虽然我在概念上同意这一点,有我提到的维修问题。
这仍然分离了关注点,并且还允许在适用的情况下重用类。
编辑1:
我发现this优秀文章。它建议分离实体并在虚拟机中使用它。尽管我不同意在虚拟机中使用实体,但我可以绕过DTO使用这个技巧。问题是延迟加载数据。由于实体不知道VM需要什么确切的数据,所以在分离实体之前应该加载所有数据。唯一的办法是急切地加载所有的数据,这也不是一个好方法。
...所以,我(团队)投入了太多时间来映射数百个对象。并创建一个域。它似乎在工作......只是将它从服务器移动到用户界面并返回......而许多人相互保证 - 重新映射到DTO就是方式......我不明白。即使使用automapper ..集合/参考将是挑战。尽管很少覆盖Newtonsoft.Json(解析器,实体和数组值解析器)......而JSON序列化/反序列化正在解决所有问题。没有DTO,没有新的对象...只管理JSON-ification ... –