我应该将Entity(Persistent)对象转换为DTO对象吗?

我的项目分层如下: –

DAL (Entity) – > BLL (DTO) – > ApplicationComponent (ViewModel)

应用程序的多个组件( ApplicationComponent )将访问BLL 。 组件包括Windows服务,Web服务,Web API和MVC控制器。

我将NHibernate Entity对象转换为DTO对象,同时将它们从DAL传递到BLL 。 在将此状态传递给ApplicationComponentBLL再次将其转换为ViewModel

这有助于我将问题与每个层中的数据处理方式分开。 我不赞成返回NHibernate Entity对象来查看以下原因: –

  • 数据暴露给我想要隐藏的UI (或只在需要时才暴露),如密码,用户types,权限等。
  • 在引用/连接上,当访问属性时, NHibernate执行额外的查询,从而使得使用延迟加载无效。
  • 向用户( Entity )暴露的不必要的数据会造成混淆和缺陷。
  • 持久性实现泄漏到BLL / UIEntity不是为UIdevise的。 它不能在所有情况下提供UI
  • 我们在DTO属性上使用属性来进行用户inputvalidation,这与Entity看起来很奇怪。

我正面临以下问题:

  • 最明显的问题是具有相同function的冗余对象。
  • 我必须在每个图层中编写映射器方法来转换对象。 这可以通过使用AutoMapper或类似的东西最小化; 但是并没有完全解决问题。

问题: –

  • 这是一个过度分离,应该避免(至less最小化)?
  • 如果这种方法是正确的,我没有看到任何简单的方法来完全绕过我上面提到的两个问题。 请build议。
  • 如果这种方法不正确,请提出更正build议。

参考文献: –

  1. 链接1build议转移Entity对象来查看哪些在我的理解不是一个好主意。

  2. Link2build议用DTO来映射Entity ,我已经同意了。

  3. Link3没有帮助。

  4. Link4build议使用像自动映射工具这样的东西。 但是它还没有完全解决问题。

  5. Link5是伟大的职位。 这解释了为什么这些应该分开,我同意。 它不会评论如何最小化由此引起的开销。

  6. 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将需要什么确切的数据,所以在分离实体之前应该加载所有的数据。 唯一的办法是急于加载所有的数据,这不是一个好方法。