2

So I am trying to relate 2 tables to each other. I have a product table and an image table. I have a collection of images in the product object and a product ID in the image object/table but when it gets the product object, the image collection is empty.

Now interestingly enough, when debugging, if I inspect the context element before the product object pulls the info from it, it loads the images in the context element, and THEN it will be assigned to the product. So it works ONLY when I manually inspect the context element and it searches for the images then.

Product

public class Product
    {
        public int Id { get; set; }
        public string FriendlyUrl { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public double? Price { get; set; }
        public double? Weight { get; set; }
        public int? Stock { get; set; }
        public virtual ICollection<Image> Images { get; set; }
    }

Image

public class Image
    {
        public int Id { get; set; }
        public int ProductId { get; set; }
        public string FileName { get; set; }
    }

DBContext

 public class TheContext : DbContext
    {
        public TheContext(DbContextOptions<TheContext> options) : base(options)
        {

        }

        public DbSet<Product> Products { get; set; }
        public DbSet<Image> Images { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>().HasMany<Image>(s => s.Images);
        }
    }

Data Access

public Product GetById(string id)
        {
            Product product = _context.Products.FirstOrDefault(p => p.FriendlyUrl == id);
            return product;
        }
Brandon Turpy
  • 883
  • 1
  • 10
  • 32

2 Answers2

3

You need to load the related entity, in your case the images:

Data Access

public Product GetById(string id)
{
    Product product = _context.Products.include(p => p.Images)
                              .FirstOrDefault(p => p.FriendlyUrl == id);
    return product;
}

Read more about loading related entities here: https://msdn.microsoft.com/en-us/library/jj574232

Also, you want to dispose your context as soon as possible, to avoid memory leaks, by using a factory or instantiate the context right where it is needed.

Data Access

public Product GetById(string id)
{
    using(var context = new TheContext())
    {
        product = context.Products.include(p => p.Images)
                         .FirstOrDefault(p => p.FriendlyUrl == id);
        return product;
    }
}

Do not keep the context alive in a field variable.

Read more about the lifetime here: https://msdn.microsoft.com/en-us/data/jj729737

Jogge
  • 1,654
  • 12
  • 36
1

This is due to EF lazy loading feature. It seems that it's turned off. Meaning : You need to explicitly specify what to load. If it was turned on, collection would be loaded when it's first accessed

You can read more about it here

https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

or

http://www.entityframeworktutorial.net/EntityFramework4.3/lazy-loading-with-dbcontext.aspx

or

Entity Framework Code First Lazy Loading

Community
  • 1
  • 1
Marty
  • 3,485
  • 8
  • 38
  • 69