5

我有一些在 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 代理版本,这会导致它打嗝。请参阅ApiController 可以返回带有其他对象集合的对象吗?

所以,我可以通过这样做来关闭代理生成DbContext

    db.Configuration.ProxyCreationEnabled = false;

这确保我正在处理 POCO 而不是代理。但是,现在我的 Client 类的大多数成员都没有填充,因为是 EF 代理为我延迟加载这些成员。

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

如果不在代码中从头开始手动创建整个对象(包括任何嵌套对象),我该如何做到这一点?当然必须有一个简单的方法 - 或者至少是某种帮助类?

4

2 回答 2

3

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

在 ASP.NET MVC 中滥用模型,我经常看到使用域模型(来自 EF)作为视图模型,因为在某些情况下,域模型作为视图模型足以满足您的 UI 是正确的。但实际上它完全不同,对于复杂的 UI,例如:网格,可能需要将多个域模型组合到一个视图模型中来为您的 UI 提供数据。

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

因此,为了关注点分离,建议您创建 DTO 对象并将其与域对象(来自 EF 的 POCO 对象)分开,即使它在属性中是 1:1 映射的。

例如,如果您有 Customer 域模型,则需要有 CustomerDto。

您可以手动映射或使用AutoMapper等工具将您的域模型映射到 DTO 模型。

通过这种方式,你也可以避免你的问题。

于 2012-08-01T15:29:31.527 回答
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

于 2013-12-17T11:35:16.950 回答