EF - 如何防止急切加载以加载所有嵌套实体

时间:2016-12-25 10:46:38

标签: json asp.net-mvc entity-framework lazy-loading eager-loading

我在两个实体之间建立了manay-to-many关系:Categories< - >项目

public class CategoryMaster
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual List<SubCategoryMaster> SubCategories { get; set; }

    public List<ItemMaster> Items { get; set; } 
}

public class ItemMaster
{
    public long Id { get; set; }
    public string Name { get; set; }

    public List<CategoryMaster> Categories { get; set; }
}

每当我尝试将相关项目明确加载到所有/某些类别时,它就会给我

  • 所有相关项目
  • 与这些项目相关的类别
  • 这些类别的相关项目等等......嵌套/循环引用

       db.CategoryMaster
            .Include(x=>x.Items)
            .Include(x=>x.SubCategories.Select(y=>y.Items))
            .ToList();
    

因此,使用Json.Encode()将其序列化为* .cshtml上的JSON会导致以下错误;

A circular reference was detected while serializing an object of type 'GoGreen.Data.Entities.SubCategoryMaster'.

由于我在属性级别禁用了延迟加载,因此我不希望它在任何时间点加载所有嵌套实体(循环引用)。有没有办法加载所有相关的第一级记录,即类别和相关项目。

Related question - 但我不想采用上述两种方式中的任何一种。

注意:我更想知道为什么EF会像这样。这对我来说似乎是个错误。

3 个答案:

答案 0 :(得分:0)

第一种方法:您可以在属性上添加属性,而不想使用[ScriptIgnore]将其排除在序列化之外,如果您的实体是自动生成的,则可以创建部分类并添加自定义

第二种方法:在视图中创建仅包含所需属性的模型,并仅选择此模型并设置属性

EFcontext.Tabel.include(x=>x...).Select(x=>new MyModel { ... });

答案 1 :(得分:0)

一种解决方法,请不要杀了我:-)在加载对象之后和序列化之前,只需设置导致循环引用为null的加载对象。我尝试过它,就像一个魅力。

答案 2 :(得分:0)

使用元数据重定向。想我会帮助任何在这里跌跌撞撞的人。

[MetadataType(typeof(CategoryMasterMetadata))]
public partial class CategoryMaster
{
}


public class CategoryMasterMetadata
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonIgnore]
    public virtual List<SubCategoryMaster> SubCategories { get; set; }

    public List<ItemMaster> Items { get; set; } 
}