【问题标题】:How to prevent Entity Framework from loading all child objects如何防止实体框架加载所有子对象
【发布时间】:2016-07-16 23:49:28
【问题描述】:

我目前正在使用 Entity Framework 来构建一个使用 ASP.NET MVC 的论坛 我有 3 个主要模型 [类别] 1--* [论坛] 1--* [帖子]

如果我有 5 个类别,每个类别有 4 个论坛,每个论坛有 1000 个帖子 我只想显示类别,当我这样做时,这意味着我也选择了 20000 个帖子??

因为每个 Category 对象都有一个 List 并且每个 Forum 对象都有 List 由于映射和关系

【问题讨论】:

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


    【解决方案1】:

    您可以使用延迟加载来防止检索子对象。见here。默认情况下应该启用延迟加载。

    延迟加载是在第一次访问引用实体或实体的属性时自动从数据库加载实体或实体集合的过程。

    使用 POCO 实体类型时,延迟加载是通过创建派生代理类型的实例,然后覆盖虚拟属性以添加加载钩子来实现的。例如,当使用下面定义的 Blog 实体类时,相关的 Posts 将在第一次访问 Posts 导航属性时被加载:

    public virtual ICollection<Post> Posts { get; set; } 
    

    您可以使用.Include() 实现特定的急切加载。 例如:

    db.Forums.Include(i => i.Posts)
    

    【讨论】:

    • 谢谢先生..我已经将属性发布为 virtual ,所以我认为延迟加载已经启用:)
    • Entity Framework Core 怎么样!目前没有延迟加载之类的东西!
    • @MichałZiobro 看到这个问题stackoverflow.com/questions/40122162/…
    • 但是在这里你得到一个人而不是明确地你正在对相关项目列表或一个相关项目进行第二次查询。但是我在第一次查询N个项目,然后循环N次获取相关数据会导致N+1个问题
    • 我见过一些明确的查询,比如 blogs = blogs.context.Blogs.ToLis() ,然后是 context.Posts.Where(p => p.blogs.in(blogs).toList();然后我将此帖子添加到ChangeTracker?并且它们已被访问但没有加载更多内容。但是如果Entity Framework Core总是(急切地)加载相关实体,如果它是主要实体并且它们是依赖实体?并且不是从依赖项加载是校长?
    【解决方案2】:

    在 dbcontext 文件中设置lazyloading=false

    【讨论】:

      【解决方案3】:

      使用存储的 SQL 过程仅显示有问题的类别。我假设这个功能会被频繁使用,因此会影响性能。 SP 是预编译的,执行计划是已知的,另外你可以从 aFewTablesnJoins 中添加一个 select distinct categoryField,其中 someId=@parameter 在你的类别查询中 - 更少的 IO,管理员对性能更满意。 当然,如上所述,延迟实例化始终是一种选择。

      【讨论】:

        【解决方案4】:

        好的,我找到了这个示例,它使用了显式加载和 IN 运算符。代码如下所示:

        (依赖实体,有 FK TutorId )[Course] N ->-------- 1 [Tutor] (主体)

        (依赖实体,具有 FK SubjectId)[Course] N ->----- 1 [Subject](主体实体)

        // get all courses 
        IEnumerable<Course> courses = context.Courses.ToList(); 
        // select tutor ids from courses (C# logic, without DB access)
        IEnumerable<int> tutorIds = courses.Select(c => c.TutorId);
        // select subject ids from courses (C# logic, without DB access)
        IEnumerable<int> subjectIds = courses.Select(c => c.SubjectId); 
        
        context.Tutors.Where( t => tutorIds.Contains(t.TutorId) ).Load();
        context.Subjects.Where( s => subjectIds.Contains(s.SubjectId) ).Load();
        

        看来这应该可行,但我需要对其进行测试并给你一个提示,它是否对我有用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          • 2014-09-09
          • 1970-01-01
          • 2014-07-21
          • 1970-01-01
          • 2018-11-20
          相关资源
          最近更新 更多