【问题标题】:Again: EF 5 code first eager vs. lazy loading再说一遍:EF 5 代码优先加载与延迟加载
【发布时间】:2013-06-19 16:26:09
【问题描述】:

有很多关于急切/延迟加载的问题,但仍有一点我不清楚。我很清楚其中的区别,了解“virtual”关键字以及如何防止延迟加载。

我有一个非常简单的模型:Store、Product、ProductCategory。一个商店可以有很多产品和类别,一个产品必须属于一个商店并且必须有一个类别。为了让事情变得更简单,我在 ProductCategory 中声明了一个“产品”属性,这样我就可以按需获取属于一个类别的所有产品。这是我的课程:

public class Store
{
    public Store()
    {
        this.Product = new HashSet<Product>();
        this.ProductCategory = new HashSet<ProductCategory>();
    }

    [Key]
    public int Id { get; set; }

    [Required()]
    public string Name { get; set; }

    public ICollection<Product> Product { get; set; }
    public ICollection<ProductCategory> ProductCategory { get; set; }
}

public class Product
{
    [Key]
    public int Id { get; set; }

    public int StoreId { get; set; }

    [Required()]
    public Store Store { get; set; }

    [Required()]
    [MaxLength(50)]
    public string Name { get; set; }

    public int ProductCategoryId { get; set; }

    [Required()]
    public ProductCategory ProductCategory { get; set; }

}

public class ProductCategory
{
    public ProductCategory()
    {
        this.Product = new HashSet<Product>();
    }

    [Key]
    public int Id { get; set; }

    public int StoreId { get; set; }

    [Required()]
    public Store Store { get; set; }

    public string Name { get; set; }

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

}

在我的上下文中,我设置了 Configuration.LazyLoadingEnabled = false。不清楚的是以下查询的结果:

var product = context.Products.Include(p => p.ProductCategory).Single(p => p.Id == 1);

结果是:一个产品(预期),一个附加到产品的类别(预期),还有一个附加到类别的产品(未预期)。 据我了解 EF 5 的工作原理,它首先加载产品,然后是类别,然后“自动”将已加载的产品附加到类别实体,即使我没有告诉 EF 这样做(没有“包括(pc => pc.Product)")。如果这是正确的理解,我该如何防止将产品附加到类别?我想要的只是产品及其类别,而不是包含产品列表的类别。

【问题讨论】:

    标签: entity-framework lazy-loading eager-loading


    【解决方案1】:

    据我所知,您无法阻止这种情况(所谓的“关系修复”)。但是为什么要阻止呢?

    你的理解是正确的:

    "...自动将已加载产品附加到 类别...”。

    此处的“已加载”包括来自具有相同上下文的早期(跟踪)查询的结果和当前查询的结果。

    运行的查询没有任何含义。该查询执行您指定的操作:加载包括类别的产品(数据库中的单个 JOIN)。该查询没有将这些类别链接到所有相关产品的附加 JOIN。关系修复只发生在带有附加对象的内存中,因此不会导致不必要的查询开销。这种行为对于急切加载和延迟加载是相同的。

    【讨论】:

    • 感谢您的回答。首先,我只是想知道我对 EF 工作原理的理解是否正确。第二个“我为什么要阻止它”是因为 MVC 4 中的 JSON 序列化和递归问题。有办法处理它,但我想也许有办法不处理结果(递归),而是处理原因。如果 EF 没有那样工作,那么 JSON 序列化就不会有问题。
    猜你喜欢
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多