序列化父/子对象与EF和的WebAPI [英] Serializing Parent/Child Object to with EF and WebApi

查看:449
本文介绍了序列化父/子对象与EF和的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体框架内的以下型号:

I have the following model inside an entity framework:

public class Customer
{
[XmlIgnore]
public virtual ICollection<Customer> Children { get; set; }

public string Name { get; set; }
}

现在我尝试这个序列使用Web API:

Now I try to serialize this using web api:

public class CustomerController:ApiController {
   public HttpResponseMessage GetAll()
   {
     using (var tc = new DataContext())
     {
        List<Customer> allCustomers = tc.Customers.ToList();
        return Request.CreateResponse(HttpStatusCode.OK, allCustomers);              
     }
   }
}

当我这样做,并呼吁使用POST方法
我收到以下错误:

When I do this and call the method using POST I receive the following error:

在'ObjectContent`1类型没有序列化反应机构
  内容类型应用/ JSON的;字符集= UTF-8

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8

的InnerException:错误
  正从'儿童'的价值
  System.Data.Entity.DynamicProxies.Customer

InnerException: "Error getting value from 'Children' on 'System.Data.Entity.DynamicProxies.Customer"

的InnerException(2):的
  ObjectContext的实例已被设置,并且不能再用于
  需要连接的业务。

InnerException(2): "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

customers.Children目前是一个空列表。

customers.Children is currently an empty List.

我猜出现这个问题,因为孩子们是相同类型的客户造成一个无限循环系列化的。 (我没有更好的词语来形容)

My guess this problem occurs because Children is of the same type as Customer causing an "infinite serialization loop". (I got no better words to describe that)

我已经尝试过XmlIgnore至prevent该属性被序列化,但没有效果。

I already tried XmlIgnore to prevent that property to be serialized but with no effect.

推荐答案

不要声明导航属性为虚拟或禁用的延迟加载行为。延迟加载默认情况下启用并通过创建派生代理类型的实例,然后覆盖虚拟属性以添加装载钩来实现的。所以,如果你想与XML序列化的工作,我建议您关闭延迟加载:

Don't declare that navigation property as virtual or disable Lazy Loading behavior. Lazy loading is enable by default and is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook. So, if you want to work with XML serializer I recommend you turn off lazy loading:

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
    } 
}

如果你要加载的相关实体(孩子),你可以使用包含扩展方法一查询的一部分。这种行为称为预先加载

In case you want to load the related entity (Children), you can use the Include extension method as part of a query. This behavior is called Eager Loading.

List<Customer> allCustomers = tc.Customers.Include(c=>c.Children).ToList();

这些链接可以帮助您更好地了解我在我的答案解释:

These links can help you to understand better what I explain in my answer:

如果您从您的导航属性中删除虚拟关键字,该POCO实体不符合在第二环节中的要求,因此,EF不会创建一个代理类懒加载您的导航性能。但是,如果你禁用延迟加载,即使您的导航性能是虚拟,他们将不会在任何实体加载。这是很好的主意禁用延迟加载,当您使用的是串行器。最串行通过在类型的实例访问每个属性工作

If you remove the virtual keyword from your navigation properties, the POCO entity not meet the requirements described in the second link, so, EF won't create a proxy class to lazy load your navigation properties. But if you disabled lazy loading, even when your navigation properties are virtual, they won't be loaded in any entity. It's good idea disable lazy loading when you are using a serializer. Most serializers work by accessing each property on an instance of a type.

这篇关于序列化父/子对象与EF和的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆