我在EF Code First上下文中使用了一些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。
如果不在代码中手动创建整个对象(包括任何嵌套对象),我该怎么做?当然必须有一个简单的方法 - 或者至少是某种辅助类?
答案 0 :(得分:3)
您的问题涉及如何为应用程序设计架构。从技术上讲,在一个应用程序中有更多的模型:不同层的域模型,数据传输对象或视图模型:业务逻辑层,分布层和表示层。
在ASP.NET MVC中滥用模型,我经常看到使用Domain模型(来自EF)作为视图模型,因为在某些情况下,作为视图模型的域模型对于UI来说已经足够了。但实际上它是完全不同的,使用复杂的用户界面,例如网格,可能需要在一个视图模型中组合多个域模型,以便为UI提供数据。
与分布层,asp.net web api类似,消费者可能需要多个域模型才能执行某些操作。它通常不是100%域模型作为数据传输对象。
因此,为了分离关注点,建议您应该使用域对象(来自EF的POCO对象)创建和分离DTO对象,即使它在属性中以1:1映射。
示例,如果您有客户域模型,则需要拥有CustomerDto。
您可以手动映射或使用AutoMapper等工具将您的域模型映射到DTO模型。
通过这种方式,您还可以避免出现问题。
答案 1 :(得分:1)
我知道你得到了答案,但是,你可能会想看看这个:
Windows Communication Foundation(WCF)无法直接序列化或反序列化POCO代理类型,因为DataContractSerializer序列化引擎只能序列化和反序列化已知类型。代理类型不是已知类型。有关更多信息,请参阅“使用POCO实体”主题中的“序列化POCO代理”部分。要将POCO代理序列化为POCO实体,请使用ProxyDataContractResolver类在序列化期间将代理类型映射到POCO类型。
http://msdn.microsoft.com/en-us/library/vstudio/ee705457(v=vs.100).aspx