将EF代理对象转换为原始POCO对象的最佳方法是什么?

时间:2012-08-01 14:56:48

标签: c# asp.net-mvc-4 asp.net-web-api entity-framework-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代理版本,这导致它打嗝。见Can an ApiController return an object with a collection of other objects?

因此,我可以通过对DbContext

执行此操作来关闭代理生成
    db.Configuration.ProxyCreationEnabled = false;

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

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

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

2 个答案:

答案 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