DTO模式+延迟加载+实体框架+ ASP.Net MVC +自动映射器

时间:2012-06-06 06:00:10

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

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

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

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

我们的后端架构如下( WCF服务 - >经理 - >存储库 - >实体框架(POCO)

在我们的应用程序中,我们不使用View Models,因为我们不想要另一个MVC应用程序的映射层,我们只使用DTO作为View Models。

通常,我们为域,例如Customer,CustomerLite等提供Normal和Lite DTO( Lite对象的属性少于普通)。

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

例如,

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

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

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

说到自动映射,我们映射CustomerViewDetailsDTO,我们将从Lazy Loading(实体框架)获取其他数据(特定视图不需要)。

我的问题:

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

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

1 个答案:

答案 0 :(得分:11)

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

  

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

换句话说,使用没有预先加载集合的延迟加载会导致实体框架转到数据库并一次将结果返回一行。

使用jsRender作为模板,因为它比JQuery模板快得多: Render Bemchmark 以下是有关如何使用它的一个很好的信息:Reducing JavaScript Code Using jsRender Templates in HTML5 Applications

  

通常,我们为域名提供Normal和Lite DTO,例如Customer,   CustomerLite等(Lite对象的属性少于Normal)。

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

  

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

对一个视图使用一个ViewModel,您不必担心可维护性。我个人通常创建一个基础的abtract类,并且对于编辑,创建或列表,我继承该类并添加特定于视图的属性。因此,对于示例,Create视图不需要PropertyId(因为有人可以劫持您的帖子并将其发布),因此只有Edit和List ViewModels才会公开PropertyId属性。

  

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

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

  

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

来源:Autoprojecting LINQ queries

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

此致