我应该将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
(或只在需要时才暴露),如密码,用户types,权限等。 - 在引用/连接上,当访问属性时,
NHibernate
执行额外的查询,从而使得使用延迟加载无效。 - 向用户(
Entity
)暴露的不必要的数据会造成混淆和缺陷。 - 持久性实现泄漏到
BLL
/UI
。Entity
不是为UI
devise的。 它不能在所有情况下提供UI
。 - 我们在
DTO
属性上使用属性来进行用户inputvalidation,这与Entity
看起来很奇怪。
我正面临以下问题:
- 最明显的问题是具有相同function的冗余对象。
- 我必须在每个图层中编写映射器方法来转换对象。 这可以通过使用
AutoMapper
或类似的东西最小化; 但是并没有完全解决问题。
问题: –
- 这是一个过度分离,应该避免(至less最小化)?
- 如果这种方法是正确的,我没有看到任何简单的方法来完全绕过我上面提到的两个问题。 请build议。
- 如果这种方法不正确,请提出更正build议。
参考文献: –
-
链接1build议转移
Entity
对象来查看哪些在我的理解不是一个好主意。 -
Link2build议用
DTO
来映射Entity
,我已经同意了。 -
Link3没有帮助。
-
Link4build议使用像自动映射工具这样的东西。 但是它还没有完全解决问题。
-
Link5是伟大的职位。 这解释了为什么这些应该分开,我同意。 它不会评论如何最小化由此引起的开销。
-
Link6再次没有帮助。
编辑1:
我刚刚阅读这个优秀的答案,build议使用Entity
, 如果可能的话在UI
。 它仍然不适用于我的大部分项目。
编辑2:
另一个优秀的postbuild议我现在正在做两种方法。 它仍然没有提出一种方法来尽量减less开销。
案例1:DAL(实体) – > BLL(DTO):
NHibernate需要声明我的实体的属性为virtual
的延迟加载情况。 参考这个和这个 。 所以,有一个范围可以假设NHibernate为实体做一些事情(为延迟加载创build代理等),更好的是我们不会去捅它。 更好的是我们将实体转换成DTO。 然后,我们可以以任何我们想要的方式使用DTO。 当然,缺点是额外的编码和维护。
情况2:BLL(DTO) – > ApplicationComponent(ViewModel)
因为我们上面已经断开了NHibernate(通过将Entity复制到DTO),所以我们可以自由地重复使用DTO将数据传递给View。 所以只要有可能,我们可以重用DTO。 如果不可能,我们可以创build新的ViewModel并将其映射到DTO。
在互联网上很多post强烈build议为每个视图创build新的ViewModel。 虽然我在概念上同意这一点, 有我提到的维修问题。
这仍然将问题分开,并允许在适用的情况下重用课程。
编辑1:
我发现这个优秀的职位。 它build议分离实体并在VM中使用它。 即使我不同意在VM中使用实体,我可以绕过DTO使用这个技巧。 问题是延迟加载数据。 由于实体不知道VM将需要什么确切的数据,所以在分离实体之前应该加载所有的数据。 唯一的办法是急于加载所有的数据,这不是一个好方法。