我在实体框架内有以下模型:
public class Customer
{
[XmlIgnore]
public virtual ICollection<Customer> Children { get; set; }
public string Name { get; set; }
}
现在我尝试使用 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 调用该方法时
我收到以下错误:
“ObjectContent`1”类型未能序列化响应正文
内容类型'application/json;字符集=utf-8
内部异常:“错误
从“孩子”身上获取价值
'System.Data.Entity.DynamicProxies.Customer'
内部异常(2):“
ObjectContext 实例已被释放,不能再用于
需要连接的操作。”
customers.Children 目前是一个空列表。
我猜测出现此问题是因为 Children 与 Customer 属于同一类型,导致“无限序列化循环”。 (我没有更好的词来形容)
我已经尝试过 XmlIgnore 来阻止该属性被序列化,但没有效果。
不要将该导航属性声明为virtual
或禁用延迟加载行为。延迟加载默认启用,并通过创建派生代理类型的实例然后覆盖来实现virtual
属性来添加加载钩子。因此,如果您想使用 XML 序列化程序,我建议您关闭延迟加载:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
如果您想加载相关实体(Children
),您可以使用Include
扩展方法作为查询的一部分。这种行为称为急切加载.
using System.Data.Entity; // For extension method `Include`
List<Customer> allCustomers = tc.Customers.Include(c=>c.Children).ToList();
这些链接可以帮助您更好地理解我在回答中解释的内容:
-
加载相关实体 https://msdn.microsoft.com/en-us/data/jj574232.aspx
- 创建 POCO 代理的要求 https://msdn.microsoft.com/en-us/library/vstudio/dd468057(v=vs.100).aspx
如果您删除virtual
导航属性中的关键字,POCO 实体不满足第二个链接中描述的要求,因此,EF 不会创建代理类来延迟加载您的导航属性。但是如果您禁用了延迟加载,即使您的导航属性是virtual
,它们不会被加载到任何实体中。当您使用序列化器时,最好禁用延迟加载。大多数序列化器通过访问类型实例上的每个属性来工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)