我有以下模特:
public class Category
{
public virtual ICollection<Product> Products{get;set;}
public Product()
{
Products = new HashSet<Product>();
}
}
public class Product
{
public Guid CategoryId{get;set;}
public virtual Category {get;set;}
}
现在,如果我执行以下语句:
var list = await UoW.Categories.Query.Where(x=>x.Name.Contains("Mob")).ToListAsync();
并从MVC控制器操作返回list
为JSON
。它抛出以下异常:
A circular reference was detected while serializing an object of type
'System.Data.Entity.DynamicProxies.Category_7C2191CFExxxxxxx'.
这种情况正在发生,因为Products
集合不为空,而每个Product
又包含Category
。
虚拟属性自动上传的原因是什么?
编辑: - 事实证明Json Serializer正在访问属性并导致EF加载它们。我按照haim770的建议关闭LazyLoading
。
答案 0 :(得分:1)
原因是实体框架代理拦截了对context.Configuration.LazyLoadingEnabled = false;
属性的访问调用并自动填充它。
你可以明确地关闭Lazy-Loading:
Category
您还可以将<{1}}列表投影到新列表中,并仅填充所需的属性。例如:
var list = await UoW.Categories.Query.Where(x=>x.Name.Contains("Mob"))
.Select(x => new Category {
Id = x.Id,
Name = x.Name
}).ToListAsync();
答案 1 :(得分:0)
WCF尝试遍历您的对象并序列化整个对象图。如果启用了延迟加载(默认情况下),它将停留在此循环引用中。
一个选项是关闭延迟加载,因为haim770建议。另一种方法是返回Data Transfer Objects而不是直接返回EF对象。
也可以返回您的对象图,其中圆形参考完整无缺。但是,您需要创建自定义DataContractSerializerOperationBehavior和自定义属性以应用该行为。 Sowmy Srinivasan的blog post有详细信息。