实体框架Code First懒加载

31

我有两个对象类

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    // Navigation
    public ICollection<Product> Products { get; set; }
}

public class Product
{
    public Guid Id { get; set; }

    // Navigation
    public User User { get; set; }
    public Guid User_Id { get; set; }

    public string Name { get; set; }
}

当我使用 dataContext 加载用户时,获取到的产品列表为 null (这是正常的)。

如果我在 Products 列表上添加 "virtual" 关键字,

public virtual ICollection<Product> Products { get; set; }
当我加载用户时,我也得到了产品列表。这是为什么?我认为“虚拟”关键字被用来不加载实体,除非您显式地使用“Include”语句。我想我理解错了。

1
你可以使用 context.ContextOptions.LazyLoadingEnabled = false; 来强制上下文不使用 LazyLoading。 - patel.milanb
使用 dbContext,可以通过 context.Configuration.LazyLoadingEnabled = false; 来禁用延迟加载。 - VivekDev
2个回答

67

这是错误的

"virtual"关键字用于当您显式指定(使用“Include”语句)时不加载实体。

延迟加载意味着当您首次访问集合或导航属性时,实体将自动加载,并且这将在透明的情况下发生,就像它们始终与父对象一起加载。

使用“include”是按需加载,当您指定要查询的属性时才会加载。

virtual关键字的存在只与延迟加载有关。 virtual关键字允许实体框架运行时为您的实体类及其属性创建动态代理,并以此支持延迟加载。 没有虚拟化,将不支持延迟加载,并且您将在集合属性上获得null。

事实是您可以在任何情况下使用“include”,但是如果没有延迟加载,它是访问集合和导航属性的唯一方式。


“延迟加载”意味着实体将在您首次访问集合时自动加载。这意味着如果我从未访问过user.Products属性,那么产品不会被加载,是吗? - Catalin
5
@RaraituL 是的,没错。在调试时,实际上你是访问属性,如果支持惰性加载,它们就会被加载。因此,你可以使用 SQL Profiler 或类似工具来调试发送到数据库的实际查询。 - archil
@archil:如果我在集合中不写virtual并使用include,那么它也会在仅需要时加载某些内容,对吗?就像延迟加载一样?那么区别是什么? - azure boy

4

我猜您正在查询一个懒加载的属性,而该属性位于ef上下文中:

using (var db = new Context())
{
    var user = db.Users.Where(...);

    var products = user.Products; // being loaded right away
}

尝试离开它:

User user;
using (var db = new Context())
{
    user = db.Users.Where(...);

    // I guess you will need here:
    // .Include(u => u.Products)
}
var products = user.Products; // what error will you get here?

不使用"virtual"关键字:User user = db.Users.First(); 在调试模式下,user.Products为null。 使用"virtual"关键字:User user = db.Users.First(); 在调试模式下,user.Products是一个产品列表。 - Catalin
@RaraituL:正如archil已经提到的,你必须在Code First方法中使用virtual关键字才能实现延迟加载。然后你可以随时开启或关闭它。 - abatishchev
但是在“user.Products”之前,上下文已经被“关闭”,那么如果有上下文,延迟加载将如何工作? - Nerf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接