2012-08-01 48 views
5

我在EF Code First上下文中使用了一些POCO对象。所以,当我用数据填充它们时,实际上我正在处理EF代理对象而不是POCO本身。将EF代理对象转换为原始POCO对象的最佳方式是什么?

我有一个ASP.NET MVC4 ApiController返回我的POCO对象,我将在我的客户端应用程序消耗。

我的“GET”方法看起来是这样的:

// GET api/Clients/5 
    public Client GetClient(int id) 
    { 
     Client client = db.Clients.Find(id); 
     if (client == null) 
     { 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); 
     } 

     return client; 
    } 

这并不实际工作,因为当串行尝试序列Client对象,它实际上是在处理与EF代理的版本,这将导致它打嗝。见Can an ApiController return an object with a collection of other objects?

所以,我可以这样做是为了我的DbContext关闭代理代:

db.Configuration.ProxyCreationEnabled = false; 

这保证了我处理与POCO,而不是代理。但是,现在我的Client类中的大多数成员都没有填充,因为它是EF代理懒惰加载这些给我的。

所以我真正想要的是使用EF代理类来获取数据,然后在最后一分钟从我的方法返回原来的POCO。

我怎么能做到这一点,而无需手动从头创建整个对象(包括任何嵌套对象)的代码?当然,必须有一个简单的方法 - 或者至少是某种助手类?

回答

3

您的问题涉及如何设计应用程序的体系结构。从技术上讲,在一个应用程序中有更多的模型:不同层的域模型,数据传输对象或视图模型:业务逻辑层,分布层和表示层。模型的

滥用在ASP.NET MVC中,我经常看到使用领域模型(从EF)作为视图模型,因为在某些情况下是正确的域模型视图模型是不够你的UI。但实际上,它与使用复杂的用户界面非常不同,例如:网格,可能需要多个域模型才能在一个视图模型中合并,以便为您的用户界面提供数据。

与分布层,asp.net web api类似,消费者可能需要多个领域模型来做一些事情。它通常不是100%的域模型作为数据传输对象。

因此,对于关注的分离,它会建议你应该创建与域对象(从EF POCO对象)单独DTO的对象,即使它被映射1:1的属性。

例如,如果您有客户域模型,则需要拥有CustomerDto。

您可以手动映射或使用工具,如AutoMapper,映射你的域模型到DTO模式。

用这种方法你也可以避免你的问题的东西。

+2

+1暴露DTO的远程客户端是最好的一段路要走。它使您可以完全控制通过线路发送的数据。 – 2012-08-01 15:53:57

+0

谢谢,我会检查AutoMapper - 这听起来就像我正在寻找的“某种助手类”。 – 2012-08-01 22:13:46

1

我知道,你得到的答案,但是,可能你会想看看这个:

的POCO代理类型不能直接序列化或由Windows Communication Foundation的反序列化(WCF) ,因为DataContractSerializer序列化引擎只能序列化和反序列化已知类型。代理类型不是已知的类型。有关更多信息,请参阅使用POCO实体主题中的序列化POCO代理部分。要将POCO代理序列化为POCO实体,请在序列化期间使用ProxyDataContractResolver类将代理类型映射到POCO类型。

http://msdn.microsoft.com/en-us/library/vstudio/ee705457(v=vs.100).aspx

+0

有趣,谢谢。 – 2013-12-17 15:43:20

相关问题