我有一些在 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。
如果不在代码中从头开始手动创建整个对象(包括任何嵌套对象),我该如何做到这一点?肯定有一个简单的方法 - 或者至少是某种辅助类?
最佳答案
您的问题涉及如何为应用程序设计架构。从技术上讲,一个应用程序中有多个模型:域模型、数据传输对象或不同层的 View 模型:业务逻辑层、分发层和表示层。
在 ASP.NET MVC 中滥用模型,我经常看到使用域模型(来自 EF)作为 View 模型,因为在某些情况下,域模型作为 View 模型足以满足您的 UI 是正确的。但实际上它是完全不同的,对于复杂的 UI,例如:网格,可能需要将多个域模型组合在一个 View 模型中以为您的 UI 提供数据。
与分发层、asp.net web api 类似,消费者可能需要多个领域模型来做某事。它通常不是 100% 域模型作为数据传输对象。
因此,为了关注点分离,建议您创建 DTO 对象并将其与域对象(来自 EF 的 POCO 对象)分开,即使它在属性中映射为 1 : 1。
例如,如果您有 Customer 域模型,则需要有 CustomerDto。
您可以手动映射或使用类似 AutoMapper 的工具, 将您的域模型映射到 DTO 模型。
通过这种方式,您还可以避免遇到问题。
关于c# - 将 EF 代理对象转换为原始 POCO 对象的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11761961/