0

Im trying to figure out a nice way to populate a nested collection model. I have the following in my viewmodel.

public class ListViewModel
{
    public ICollection<Wish> Wishes { get; set; }
}

The Wish model looks like this:

public class Wish
{      
    public ICollection<Image> Images { get; set; }
}

Now in my controller I want to populate the ListViewModel with wishes also populate each wish with their corresponding images. What I have so far:

public IActionResult Index()
{
    ICollection wishes = _repoWish.GetAllAsync().Result;
    ICollection images = _repoImage.GetAllAsync().Result;

    var model = new ListViewModel
    {
       Wishes = wishes
    };
    return View(model);
}

I know I can make a lot of foreach statements but I want to make use of LINQ to populate each wish with their corresponding images.

**I do have a generic repository class which makes it possible for me to retrieve all images in the same manner as the wishes.

*** Think about the repositories as contexts. So instead of _repoWish and _repoImage its wishContext and imageContext

I am using ASP.NET Core 2.0 with Entity Framework Core

Anonymous
  • 1,303
  • 4
  • 19
  • 31
  • what does `_repoWish.GetAllAsync().` return ? and how are `Image` entity and `Wish` entity are connected in that result set ? – Shyju Oct 12 '17 at 20:24
  • so your wishes are not coming with the images from your database? – Zinov Oct 12 '17 at 20:27
  • You'd need loops or `linq` if you're [using a view model](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc). What is wrong with the current code you have? – adiga Oct 12 '17 at 20:28
  • @Shyju It returns an ICollection of wishes. But the wishes are not populated with their images – Anonymous Oct 12 '17 at 20:28
  • @adiga Nothing is wrong with the code. I just need an extra step to populate each wish with their images. – Anonymous Oct 12 '17 at 20:30
  • Ok, so where do you get your images from? You should add code for that also. – OctoCode Oct 12 '17 at 20:34
  • You may need to include your navigational property `Images` like `.Include("Images")` if you are fetching your data from EF LINQ – G J Oct 12 '17 at 20:36
  • @GauravSinghJantwal Yes that was what I was hoping you could help me with – Anonymous Oct 12 '17 at 20:37
  • Additionally `_repoWish.GetAllAsync().Result;` might create a deadlock, instead use `_repoWish.GetAllAsync().GetAwaiter().GetResult();` or use async/await – G J Oct 12 '17 at 20:40
  • @GauravSinghJantwal the async/await is included within the GetAllAsync() – Anonymous Oct 12 '17 at 20:41

1 Answers1

4

To load the related entities, you need to explicitly use the Include method call when you query the Wishes collection to eager load the Images property.

Also make sure you await your async calls.

var wishesWithImages = await yourDbContext.Wishes
                                          .Include(g => g.Images)
                                          .ToListAsync();

The variable wishesWithImages will be a collection of Wish objects with Images property loaded. You can now use that to populate your view model.

var vm = new ListViewModel { Wishes = wishesWithImages  };

Assuming your Wish entity has a collection property of type Images

public class Wish
{
   public int Id { set;get;}
   public ICollection<Image> Images { set;get;} 
}
public class Image
{
   public int Id { set;get;}
   public int WishId { set;get;}
   public virtual Image Image{ set;get;} 
}

As of today, Entity framework core is a light weight version of EF6 and doesn't automatically inherit all the features from EF 6. Lazy loading is not implemented yet in EF core.

Shyju
  • 214,206
  • 104
  • 411
  • 497