EF Core的预先加载、延迟加载、实体追踪

一、预先加载   

       【业务场景】

         主表为 Bogs,里面包含了List<>类型的子表 Posts,Author。

       【预先加载】

         即在一次查询时,一次性把所有的子表数据加载出来。

       【关键字】

         Include

二、延迟加载

        注意:EF中默认是延迟加载,可以减少访问数据库次数。但是EF Core中默认不使用。如果需要使用,需要安装扩展包:Microsoft.EntityFrameworkCore.Proxies

       使用方式如下:

       属性的导航会有变化。

      【延迟加载】

       即按需加载。当我们需要时才会加载,比如例子中,我们查询时,才会加载子表数据。

 三、实体追踪

      EF每次执行查询的时候,实际都会从数据库拿到一个数据查询的快照,这个实体快照包含了所有数据的实体状态和实体跟踪。直到SaveChange()执行的时候,我们才会去保存实体,数据库才会真正的保存实体。

      【对比】

       默认情况下,跟踪返回实体类型的查询。 这表示可以更改这些实体实例,然后通过 SaveChanges() 持久化这些更改。 在以下示例中,将检测到对博客分级所做的更改,并在 SaveChanges() 期间将这些更改永久保存到数据库中。

      在跟踪查询中返回结果时,EF Core 将检查上下文中是否已存在实体。 如果 EF Core 找到现有的实体,则返回同样的实例。 EF Core 不会用数据库值覆盖该实体中实体属性的当前值和原始值。 如果未在上下文中找到该实体,EF Core 将创建新的实体实例,并将其附加到上下文。 查询结果不会包含任何已添加到上下文但尚未保存到数据库中的实体。

      非实体跟踪时,在只读方案中使用结果时,非跟踪查询十分有用。 可以更快速地执行非跟踪查询,因为无需设置更改跟踪信息。 如果不需要更新从数据库中检索到的实体,则应使用非跟踪查询。 可以将单个查询替换为非跟踪查询。 非跟踪查询也会根据数据库中的内容提供结果,但不考虑本地更改或已添加的实体。

var blogs = context.Blogs
    .AsNoTracking()
    .ToList();

    还可以在上下文实例级别更改默认跟踪行为:

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

var blogs = context.Blogs.ToList();

EF Core 不会跟踪结果中包含的无键实体实例。 但 EF Core 会根据上述规则跟踪带有键的实体类型的所有其他实例。

 

posted on 2025-07-02 10:29  木乃伊人  阅读(27)  评论(0)    收藏  举报

导航