【问题标题】:DTO Pattern + Lazy Loading + Entity Framework + ASP.Net MVC + Auto MapperDTO 模式 + 延迟加载 + 实体框架 + ASP.Net MVC + 自动映射器
【发布时间】:2012-06-10 03:42:22
【问题描述】:

首先,很抱歉问题很长,但我必须提供一些基本信息。

我们正在创建一个使用 ASP.net MVC、JQuery 模板、实体框架、WCF 的应用程序,并且我们使用 POCO 作为我们的域层。在我们的应用程序中,有一个 WCF 服务层与 ASP.net MVC 应用程序交换数据,它使用从 WCF 到 MVC 的数据传输对象 (DTO)。

此外,在我们的 WCF 服务层中转换 Domain-TO-DTO 时,应用程序通过使用 AutoMapper 在实体框架中使用延迟加载。

我们的后端架构如下(WCF Services -> Managers -> Repository -> Entity Framework(POCO)

在我们的应用程序中,我们不使用视图模型,因为我们不希望 MVC 应用程序有另一个映射层,并且我们只使用 DTO 作为视图模型。

一般来说,我们有针对客户、CustomerLite 等域的 Normal 和 Lite DTO(Lite 对象的属性比 Normal 少)。

现在我们在使用 DTO 时遇到了一些困难,因为我们的 DTO 结构变得越来越复杂,并且当我们考虑可维护性(使用 DTO 的一般层次结构)时,我们会失去性能。

例如,

我们有客户视图页面和我们的 DTO 层次结构如下

 public class CustomerViewDetailsDTO
 {
   public CustomerLiteDto Customer{get;set;}
   public OrderLiteDto Order{get;set;}
   public AddressLiteDto Address{get;set;}
 }

在这种情况下,我们不希望 OrderLiteDto 的某些字段用于此视图。但是其他一些视图需要该字段,因此为了方便我们使用该结构。

当涉及到自动映射时,我们映射 CustomerViewDetailsDTO,我们将从延迟加载(实体框架)获取额外数据(特定视图不需要)。

我的问题:

  1. 在考虑可维护性的同时,我们可以使用任何机制来提高性能吗?

  2. 是否可以将 Automapper 与更多基于地图视图的映射功能一起用于同一 DTO?

【问题讨论】:

  • 冗长?我希望每个问题都这么短:)

标签: asp.net-mvc entity-framework lazy-loading automapper dto


【解决方案1】:

首先不要使用延迟加载,因为它可能会导致 Select N+1 问题或类似问题。

Select N + 1 是数据库所在的数据访问反模式 以次优方式访问。

换句话说,使用延迟加载而不预先加载集合会导致 Entity Framework 进入数据库并一次将结果带回一行。

将 jsRender 用于模板,因为它比 JQuery 模板快得多: Render Bemchmark 这里有一个关于如何使用它的好信息:Reducing JavaScript Code Using jsRender Templates in HTML5 Applications

一般来说,我们有针对客户等域的 Normal 和 Lite DTO, CustomerLite 等(Lite 对象的属性比 Normal 少)。

您的正常 DTO 可能是 ViewModel,因为 ViewModel 可能会或可能不会一对一地映射到 DTO,并且 ViewModel 通常包含从视图推回的逻辑,或者帮助根据用户的响应将数据推回模型。 DTO 没有任何行为,其目的是减少应用程序层之间的调用次数。

在考虑可维护性的同时,我们可以使用任何机制来提高性能吗?

为一个视图使用一个 ViewModel,您不必担心可维护性。就个人而言,我通常创建一个作为基础的抽象类,对于编辑、创建或列表,我继承该类并添加特定于视图的属性。因此,例如,创建视图不需要 PropertyId(因为有人可以劫持您的帖子并发布它),因此只有 Edit 和 List ViewModels 具有 PropertyId 属性。

是否可以将 Automapper 与更多基于地图视图的映射功能一起用于相同的 DTO ?

您可以使用 AutoMapper 来定义每张地图,但问题是,地图会有多复杂。每个视图使用一个 ViewModel,您的地图将易于编写和维护。必须指出,不建议在数据访问代码中使用 Automapper 为:

AutoMapper 的一个缺点是来自域对象的投影 仍然强制查询和加载整个域对象。

来源:Autoprojecting LINQ queries

您可以使用目前受限的一组扩展来加快数据访问代码中的映射:Stop using AutoMapper in your Data Access Code

问候

【讨论】:

  • 感谢您的回答,非常感谢。有时,关闭延迟加载是一件麻烦事,因为我们必须手动包含必要的连接。我同意你的观点,N+1 问题和延迟加载应该小心处理。我们总是使用 Entity Profiler (efprof.com) 来分析 Entity Framework 的性能。我们没有在持久层中使用 Auto Mapper。基本上,我同意一个视图模型的视图,在我们的例子中,它将成为一个维护不友好的页面的一个 DTO。
  • 没问题。是的,efprofiler 是一款很棒的软件。如果这是您需要的信息,请将其标记为答案。
猜你喜欢
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多