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 加载用户时,我得到的产品列表为空(这没关系)。

如果我在产品列表中添加“虚拟”关键字,

public virtual ICollection<Product> Products { get; set; }

当我加载用户时,我也会得到产品列表。

为什么会这样?我认为“虚拟”关键字用于不加载实体,除非您明确说明(使用“包含”语句)

我想我全都错了

4

2 回答 2

67

这是错误的

“virtual”关键字用于不加载实体,除非您明确说明(使用“Include”语句)

延迟加载意味着实体将在您首次访问集合或导航属性时自动加载,并且这将透明地发生,就好像它们总是与父对象一起加载一样。

当您指定要查询的属性时,使用“包含”按需加载。

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

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

于 2012-07-13T11:27:39.607 回答
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?
于 2012-07-13T11:24:59.577 回答