EF无需访问

时间:2015-04-22 14:15:10

标签: c# entity-framework asp.net-mvc-5

我有以下模特:

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控制器操作返回listJSON。它抛出以下异常:

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

2 个答案:

答案 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有详细信息。