我有一些在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。

如何在不从头开始手动创建整个对象(包括任何嵌套对象)的情况下做到这一点?当然,必须有一种简单的方法-至少是某种形式的 helper 类?

最佳答案

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

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

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

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

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

您可以手动映射,也可以使用AutoMapper之类的工具将域模型映射到DTO模型。

通过这种方式,您还可以避免出现问题。

关于c# - 将EF代理对象转换为原始POCO对象的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11761961/

10-12 00:27
查看更多