1
votes

There are a lot of questions about eager/lazy loading, but still there is one point that is not clear to me. I know the difference quite well, understand the "virtual" keyword and how to prevent lazy loading.

I have a very simple model: Store, Product, ProductCategory. A store can have many products and categories, a product must belong to a store and must have a category. To make things easier I have declared a "Products" property in ProductCategory so I can get all products belonging to one category on demand. Here are my classes:

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; }

}

In my context I set Configuration.LazyLoadingEnabled = false. What is not clear is the result of the following query:

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

The result is: one product (expected), one category attached to product (expected), but also one product attached to category (not expected). As far as I understand how EF 5 works it first loads the product, then the category, and then attaches "automatically" the already loaded product(s) to the category entity even though I have not told EF to do this (no "Include(pc => pc.Product)"). If this is the right understanding, how can I prevent attaching the product(s) to the category? All I want is the product and its category, NOT the category with its list of products.

1

1 Answers

1
votes

As far as I know you can't prevent that (what is called "relationship fixup"). But why do you want to prevent it?

Your understanding is correct:

"...attaches automatically the already loaded product(s) to the category...".

Here "already loaded" includes results from earlier (tracked) queries with the same context and the result of the current query.

There is no implication for the query that is run. The query does what you specified: Load products including categories (single JOIN in the DB). The query does not have an additional JOIN that links those categories to all related products. Relationship fixup only happens in memory with attached objects and therefore doesn't cause unnecessary query overhead. This behaviour is the same for eager and lazy loading.