当前位置: 首页 > 知识库问答 >
问题:

EF6中的渴望、懒惰和显式加载

荀子轩
2023-03-14

我已经阅读了本教程和这篇文章,但我不明白每种加载类型的确切用途。

我解释

我有这个POCO:

public partial class dpc_gestion
{
    public dpc_gestion()
    {
        this.ass_reunion_participant = new HashSet<ass_reunion_participant>();
        this.dpc_participant = new HashSet<dpc_participant>();
        this.dpc_reunion = new HashSet<dpc_reunion>();
    }

    public int dpc_id_pk { get; set; }
    public Nullable<int> dpc_id_gdp_fk { get; set; }
    public Nullable<int> dpc_id_theme { get; set; }
    public int dpc_id_animateur_fk { get; set; }
    public Nullable<System.DateTime> dpc_date_creation { get; set; }
    public Nullable<System.DateTime> dpc_date_fin { get; set; }
    public Nullable<System.DateTime> dpc_date_engag_anim { get; set; }
    public Nullable<bool> dpc_flg_let_engag_anim { get; set; }
    public Nullable<bool> dpc_flg_fsoins_anim { get; set; }
    public virtual ICollection<ass_reunion_participant> ass_reunion_participant { get; set; }
    public virtual theme_dpc theme_dpc { get; set; }
    public virtual gdp_groupe_de_pair gdp_groupe_de_pair { get; set; }
    public virtual ICollection<dpc_participant> dpc_participant { get; set; }
    public virtual ICollection<dpc_reunion> dpc_reunion { get; set; }
}

我明白这一点:

>

  • 对于懒惰加载:因为加载是懒惰的,如果我调用dbsetdpc_gestion将不会加载所有导航属性。这种类型的加载在性能和响应性方面是最好的。默认情况下启用它,如果我想重新启用它,我必须设置:

    context.Configuration.ProxyCreationEnabled = true;    
    context.Configuration.LazyLoadingEnabled = true;
    

    对于即时加载,它不是懒惰的:当我加载dpc\u-gestion时,它加载了所有导航属性。可以使用include方法加载导航属性。要启用此加载类型,请执行以下操作:

    context.Configuration.LazyLoadingEnabled = false;
    

    对于显式加载,它类似于渴望加载,但我们使用Load方法而不是include

    所以我想知道:

    1. 如果这个小简历是真的?
    2. 如果是真的,那么急切加载和显式加载有什么区别?
    3. 如果我使用延迟加载,我调用例如dpc_gestion.dpc_participant,导航属性是否加载?或者我会得到一个例外?
    4. 是否有急切加载或显式加载在性能和响应性方面优于懒惰加载的情况?

    谢谢

  • 共有3个答案

    太叔高义
    2023-03-14

    在这里,您将学习如何在实体图中显式加载相关实体。显式加载在EF 6和EF Core中都有效。

    即使禁用了延迟加载(在EF 6中),仍然可以延迟加载相关实体,但必须通过显式调用完成。使用Load()方法显式加载相关实体。考虑下面的例子。

    using (var context = new SchoolContext())
    {
         var student = context.Students
                                  .Where(s => s.FirstName == "Bill")
                                 .FirstOrDefault<Student>();
    
         context.Entry(student).Reference(s => s.StudentAddress).Load(); 
         // loads StudentAddress
         context.Entry(student).Collection(s => s.StudentCourses).Load(); 
         // loads Courses collection      
    }
    

    在上述示例中,上下文。条目(学生)。参考文献

    同样地,context.Entry(student).Collection(s=

    using (var context = new SchoolContext())
    {
        var student = context.Students
                        .Where(s => s.FirstName == "Bill")
                        .FirstOrDefault<Student>();
    
        context.Entry(student)
                 .Collection(s => s.StudentCourses)
                   .Query()
                .Where(sc => sc.CourseName == "Maths")
                .FirstOrDefault();
    }     
    

    在上面的示例中,集合=

    文华美
    2023-03-14

    问题1和2:

    您对延迟加载和渴望加载的解释是正确的。
    显式加载的使用与您描述的略有不同。

    EntityFramework返回IQueryable对象,这些对象基本上包含对数据库的查询。
    Load执行查询,以便其结果存储在本地。
    调用Load与调用ToList并丢弃List,而不会产生创建List的开销。

    问题3:

    如果使用延迟加载,EntityFramework将负责为您加载导航属性,因此不会出现异常
    请记住,这可能需要一段时间,并使应用程序无响应。

    问题4:

    在断开连接的情况下(例如网络应用程序),您不能使用延迟加载,因为这些对象被转换为DTO,然后不会被EntityFramework跟踪。

    另外,如果您知道要使用导航属性,那么最好立即加载它,这样您就不必等到从数据库加载导航属性。
    例如,假设您将结果存储在列表中并将其绑定到WPF DataGrid。如果DataGrid访问一个尚未加载的属性,用户将经历一个明显的超时,直到显示该属性为止。此外,应用程序在加载期间不会响应(如果不异步加载)。

    公羊喜
    2023-03-14

    如果这个小简历是真的?

    如果是真的,那么急切加载和显式加载有什么区别?

    急切加载与懒惰加载相反,但显式加载与懒惰加载相似,不同之处在于:您在代码中显式检索相关数据;当您访问导航属性时,它不会自动发生。通过获取实体的对象状态管理器条目并调用Collection,可以手动加载相关数据。加载集合或引用的方法。用于保存单个实体的属性的Load方法。

    来自techblog:

    快速加载:

    急切加载与懒惰加载相反,懒惰加载是:加载特定的一组相关对象以及查询中显式请求的对象的过程。

    显式加载:

    显式加载定义为:当查询返回对象时,不同时加载相关对象。默认情况下,在使用导航属性上的Load方法显式请求之前,不会加载它们。

    以及:

    如果我使用延迟加载并调用例如dpc\u gestion.dpc\u participant,是否加载导航属性?或者我将得到一个异常?

    您不会得到任何异常,导航属性应该加载。

    在性能和响应性方面,是否存在急切加载或显式加载优于惰性加载的情况?

    当您需要主表的所有检索行的相关数据时,急切加载通常更有效。此外,当关系不太多时,急切加载将是减少服务器上进一步查询的良好做法。但是当你知道你不会立即需要一个属性时,懒惰加载也许是一个不错的选择。而且,在数据库上下文将被处理并且不能再进行延迟加载的情况下,快速加载也是一个不错的选择。例如,考虑以下内容:

    public List<Auction> GetAuctions()
    {
        using (DataContext db = new DataContext())
        {
            return db.Aucthtml" target="_blank">ions.ToList();
        }
    }
    

    调用此方法后,您不能延迟加载相关实体,因为db已被释放,因此在这里,急切加载是一个更好的选择。

    还有一件事需要注意:延迟加载将产生多个SQL请求,而急切加载数据只需一个请求。对于解决ORMs中的n1选择问题,即时加载也是一个很好的选择。看看这篇文章:n1选择的问题是什么?

     类似资料:
    • 我有一个问题,就是基于hasMany关系从数据库中获取数据并将其发送到Larave中的api。在下面的代码中,Laravel没有给我客户id=$id的产品。我不知道为什么,我不能在$query旁边发送$id。如果我把号码写在“我有很好的安全套,但我需要自动拿。 所有api代码 先谢谢你。

    • 我正在使用教义2来绘制学术时间表。以下是对这些关系的简化观察: 一个类有事件(一对多) 事件具有类型(多对一) 一个事件有一个位置(多对一) 使用

    • 问题内容: 如果按以下方式实现单例, 此实现与延迟初始化方法有何不同?在这种情况下,实例将在加载类时创建,并且仅在第一次使用时才加载类本身(例如,Singleton.getInstance(),而当您声明实例Singleton singleton = null;时则不会)。 即使采用惰性初始化方法,该实例也是在对getInstance()的调用上创建的 我在这里想念什么吗? 问题答案: 您也可以调

    • 在Haskell中,下面的代码打印“[1,2,3,4,5”: 但是在Frege中,它抛出,代码如下: 这里唯一的区别是函数,它是从转换为和FWIW,函数是热切的。为什么整个表达式不能像Haskell中那样懒惰呢?在这里有可能实现类似弗雷格哈斯克尔的东西吗?

    • 我有对象主位置和主国家/地区 MasterLocation.java 主位置存储库.java 为什么对象MasterCountries仍然加载在findByLocationNameLikeIgnoreCase上?如何在此存储库中禁用获取主国家/地区? 谢谢

    • 我正在建立一个小博客,我想使用内置的雄辩的渴望加载,但我希望它作为一个明确的加入。 下面是我试图做的,使用连接,它可以工作,但不是我想要的方式。 我的问题是,我不能像这样在我的帖子中使用用户模型: $帖子[0]- 通过连接,用户的数据直接设置在post模型上,因此我必须像这样使用它: $帖子[0]- 问题是:我想使用我的用户模型,因为它里面有一些我想使用的方法。一个用于打印全名,一个用于打印其网址