2016-11-21 273 views
1

我的项目是分层如下: -我应该将Entity(Persistent)对象转换为DTO对象吗?

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

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

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

这有助于我分离问题以及如何在每个层中处理数据。我不赞成恢复NHibernateEntity对象可以查看以下原因: -

  • 数据获取暴露UI,我要隐藏(或仅在需要时暴露),如密码,用户类型,许可等
  • 在引用/连接处,NHibernate在访问属性时会执行额外的查询,从而使使用延迟加载无效。
  • 暴露给用户(Entity)的不必要的数据造成了错误的混淆和差距。
  • 泄漏到BLL/UI中的持久性实现。 Entity不适用于UI。它在任何情况下都不能服务于UI
  • 我们对DTO属性使用属性进行用户输入验证,这与Entity看起来很奇怪。

我现在面临以下问题这种方法: -

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

问题: -

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

参考: -

  1. Link1建议转移Entity对象可以查看这在我的理解不是一个好主意。

  2. Link2建议映射EntityDTO我已经同意了。

  3. Link3没有帮助。

  4. Link4建议使用类似自动映射工具的东西,这是可以的。但它仍然不能完全解决问题。

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

  6. Link6再次没有帮助。

编辑1:

我刚才读this外观极好回答这表明使用Entity这在UI如果可能的话。它仍然不适用于我的大部分项目。

编辑2:

另一个优秀post建议去映射双向,因为我现在做的事情。它仍然没有提出一种最小化开销的方法。

+0

...所以,我(团队)投入了太多时间来映射数百个对象。并创建一个域。它似乎在工作......只是将它从服务器移动到用户界面并返回......而许多人相互保证 - 重新映射到DTO就是方式......我不明白。即使使用automapper ..集合/参考将是挑战。尽管很少覆盖Newtonsoft.Json(解析器,实体和数组值解析器)......而JSON序列化/反序列化正在解决所有问题。没有DTO,没有新的对象...只管理JSON-ification ... –

回答

-1

案例1:DAL(实体) - > BLL(DTO):

NHibernate的需要声明我的实体的属性作为virtual懒加载的情况。请参阅thisthis。所以,我们可以假设NHibernate为实体做了一些事情(为延迟加载创建代理等),并且我们更好地嘲笑它。更好的是我们将实体转换为DTO。然后,我们可以以任何我们想要的方式使用DTO。当然,缺点是需要额外的编码和维护。

案例2:BLL(DTO) - > ApplicationComponent(视图模型)

正如我们已经断开NHibernate的(通过复制实体到DTO)以上,我们可以自由地重用DTO传递数据查看。所以,只要有可能,我们可以重用DTO。如果不可行,我们可以创建新的ViewModel并将其映射到DTO。

很多互联网上的帖子强烈建议为每个视图创建新的ViewModel。虽然我在概念上同意这一点,有我提到的维修问题。

这仍然分离了关注点,并且还允许在适用的情况下重用类。

编辑1:

我发现this优秀文章。它建议分离实体并在虚拟机中使用它。尽管我不同意在虚拟机中使用实体,但我可以绕过DTO使用这个技巧。问题是延迟加载数据。由于实体不知道VM需要什么确切的数据,所以在分离实体之前应该加载所有数据。唯一的办法是急切地加载所有的数据,这也不是一个好方法。