Darren Gansberg
Darren Gansberg

Reputation: 764

Why does my query fail to load related data whilst using Entity Framework?

I am using Entity Framework 6.1 with an entity model that consists of three entities so far, a Product, ProductImage and File. However, whilst my data is being persisted to the database successfully, I'm having some difficulties with loading the data using eager loading via the Include() method. The entities I'm using are as follows.

Product entity:

public class Product
{
    ICollection<ProductImage> images;

    public Product ()
    {
        images = new List<ProductImage>();
    }   

    public ICollection<ProductImage> Images
    {
        get { return images; }
        set { images = value; }
    }
}

File entity:

public class File
{
    private Guid fileId;

    public File()
    {
        FileId = Guid.NewGuid();
    }

    public Guid FileId
    {
        get { return fileId; }
        set { fileId = value; }
    }
}

ProductImage entity:

public class ProductImage
{
    private File file;
    private Product product;

    private ProductImage()
    {
        file = new File();
        product = new Product();
    }

    public ProductImage(Product product, File file)
    {
        this.product = product;
        this.file = file;
    }

    [Key]
    [Column(Order = 0)]
    [ForeignKey("Product")]
    public int ProductId
    {
        get { return product.ProductId; }
        set { product.ProductId = value; }
    }

    [Key]
    [Column(Order = 1)]
    [ForeignKey("File")]
    public Guid FileId
    {
        get { return file.FileId; }
        set { file.FileId = value; }
    }

    public File File
    {
        get { return file; }
        set { file = value; }
    }

    [InverseProperty("Images")]
    public Product Product
    {
        get { return product; }
        set { product = value; }
    }       
}

I then attempt to utilise the following function to load a Product, its ProductImage and the related File using the following:

static Product LoadProduct(int productId)
{
    using (var db = new ProductCatalogueDbContext())
    {
        var query = from product in db.Products
                        .Include(p => p.Images.Select(i => i.File))
                        .Where(p => p.ProductId == productId)                                                         
                        select product;
        return query.SingleOrDefault();
    }
}

Is there are a problem with the query I'm using?

Upvotes: 1

Views: 125

Answers (2)

Darren Gansberg
Darren Gansberg

Reputation: 764

Whilst I don't fully comprehend the full reasons why the data wasn't loading it turns out I was able to identify in part the cause. Instantiation of a File object in the Ctor of ProductImage and assignment of its reference to the file field, which was being returned by the File property, was causing problems.

I've encountered problems with EF loading data before when the property to be loaded doesn't actually return a null. The problem was encountered in relation to a lazy loaded entity. From what I can deduce, although this may be mistaken, it appears that unless the property returns null, EF will not actually load data from the database that is related to the property?

Upvotes: 0

marc_s
marc_s

Reputation: 754248

Yes, there is a problem with your code - you're freely mixing the SQL-like style of a LINQ query with the "dot notation" - you cannot do it like that....

I personally prefer the "dot-notation" - and in that case, you need to use that notation for all parts of your LINQ query:

 var query = db.Products
               .Include(p => p.Images.Select(i => i.File))
               .Where(p => p.ProductId == productId)
               .Select(p => p);

As far a I know, the Include doesn't have a "SQL-like" equivalent, so you would either have to "combine" it properly with the SQL-like syntax, or just use the "dot notation" all the way....

Upvotes: 1

Related Questions