我有两个模型类,地址和产品,它们在数据库中处于多对多关系。
当我尝试使用Include()
加载地址以获取产品时,当我尝试将其转换为JSON时,我得到一个circularReferenceException。这很有道理,JSON会变得无限长。
我知道,我可以通过将[ScriptIgnore]
置于一个引用列表之上来解决此问题。
但是这会导致一个新问题:我需要在两个方向上解决关系,并根据情况将它们放入JSON中。我的意思是,根据具体情况,我需要产品和引用的地址,我需要在其他地方寻找他们的产品参考;
以下是我的课程(缩短):
public class Product
{
...
[ScriptIgnore]
public List<Address> Addresses { get; set; }
}
地址类:
public class Address
{
....
public List<Product> Products { get; set; }
...
}
获取数据:
public JsonResult GetAllOrders()
{
EFDbContext context = new EFDbContext();
return Json(context.Addresses.Include(a => a.Products).ToList(), JsonRequestBehavior.AllowGet);
}
有没有办法告诉序列化器哪些引用忽略哪些引用?在上述情况下,我希望尊重Address-&gt; Product引用,但忽略其子代中的Product-&gt; Address。
我想到的唯一解决方案是遍历每个地址及其产品并删除引用。但我希望有更优雅的方式。
答案 0 :(得分:0)
您需要浏览一个没有循环引用的新对象。例如:
public static object ToAnonymousType(this Address address)
{
var products = address.Products.Select(p => p.ToAnonymousType());
return new { Id = address.Id, Products=products };
}
public static object ToAnonymousType(this Product product)
{
return new { Id = product.Id };
}
public JsonResult GetAllOrders()
{
using(var context = new EFDbContext())
{
var addresses = context.Addresses.Include(a => a.Products).ToList().Select(a => a.ToAnonymousType());
return Json(addresses, JsonRequestBehavior.AllowGet);
}
}
答案 1 :(得分:0)
在此代码中,您没有像这样定义的virtual
关键字:
public virtual IList<Product> Products { get; set; }
因此,对于看起来不错的部分,请不要添加虚拟关键字。
如果您需要使用Include
来加载属性,则意味着延迟加载被禁用,以防您可以尝试强制禁用它
public class EFDbContext: DbContext
{
public EFDbContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
您还为[ScriptIgnore]
属性添加了Addresses
,但是如何将其添加到Products
呢?
public class Address
{
....
[ScriptIgnore]
public List<Product> Products { get; set; }
...
}
您应该查看此链接以获取更多说明:Loading Related Entities