Click here to Skip to main content
15,907,328 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a very simple data structure: Product has a Review My question is how can i eagerly load all the reviews for a product? I have an Action ViewResult method for a view called ProductDetails as seen below.

C#
public ViewResult ProductDetails(int productId)
{
    Product product = repository.Products
        .FirstOrDefault(p => p.ProductID == productId);
    return View(product);
}


Within the ProductDetails view i defined this simple @HTML.DisplayFor(model => model.ProductName) and also called for a partial view @HTML.Partial("_Review", new app.models.review()); which renders the _Review Partial view into the ProductDetails view to display the related Reviews for the specific product but no luck. I couldn't find anything searching, any help would be much appreciated. Thanks in advance.
Edit:

I am using entity framework model first approach. Below are my models, take a look.

C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace EShopperTheme.Domain.Entities
{
    public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public decimal ProductPrice { get; set; }
        public string ProductCategory { get; set; }
        public string MenSubCategory { get; set; }
        public string WomenSubCategory { get; set; }
        public string KidSubCategory { get; set; }
        public string ElectronicSubCategory { get; set; }
        public string FurnitureandHomeSubCategory { get; set; }
        public string BookSubCategory { get; set; }
        public decimal ProductWeight { get; set; }
        public string AvailableSizes { get; set; }
        public string AvailableColors { get; set; }
        public string Size { get; set; }
        public string Color { get; set; }
        public decimal Discount { get; set; }
        public int UnitsInStock { get; set; }
        public Boolean ProductIsUnlimited { get; set; }
        public Boolean ProductAvailable { get; set; }
        public Boolean DiscountAvailable { get; set; }
        public byte[] MainPicture { get; set; }
        public string MainPictureMimeType { get; set; }
        public byte[] SecondPicture { get; set; }
        public string SecondPictureMimeType { get; set; }
        public byte[] ThirdPicture { get; set; }
        public string ThirdPictureMimeType { get; set; }

    }
}


Review model is below:
C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace EShopperTheme.Domain.Entities
{
    public class Review
    {
        [HiddenInput(DisplayValue=false)]
        public int ReviewId { get; set; }
        [Required]
        public int ProductID { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public string Subject { get; set; }
        [Required]
        public string Body { get; set; }
    }
}


and finally the ProductViewModel is :
C#
using EShopperTheme.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EShopperTheme.Models
{
    public class ProductsListViewModel
    {
        public IEnumerable<Product> Products { get; set; }
      
        public List<Review> Reviews { get; set; }
        public PagingInfo PagingInfo { get; set; }
        
    }
}


What I have tried:

Didn't Tried anything as far as i am new to programming.
Posted
Updated 18-Feb-16 8:25am
v5

1 solution

If you're using Entity Framework, then you need to use the Include method:
Entity Framework Loading Related Entities[^]
C#
Product product = repository.Products
    .Include(p => p.Reviews)
    .FirstOrDefault(p => p.ProductID == productId);


If you're using something else, then you need to tell us what you're using, and show us the relevant parts of the code.

EDIT:
First, update your repository to return IQueryable<...> instead of IEnumerable<...>:
C#
public interface IProductsRepository
{
    IQueryable<Product> Products { get; }
    IQueryable<Review> Reviews { get; }
    ...
}

public class EFProductRepository : IProductsRepository
{
    ...
    
    public IQueryable<Product> Products
    {
        get { return context.Products; }
    }
    
    public IQueryable<Review> Reviews
    {
        get { return context.Reviews; }
    }
    
    ...
}

Then, add the navigation properties to define the relationship between the Product and Review classes:
C#
public class Product
{
    ...
    public virtual ICollection<Review> Reviews { get; set; }
}

public class Review
{
    ...
    [Required]
    public int ProductID { get; set; }
    public virtual Product Product { get; set; }
    ...
}

Make sure you have a using System.Data.Entity; statement at the top of your controller file.

Now you can use the Include method to eagerly load the reviews for the product:
C#
Product product = repository.Products
    .Include(p => p.Reviews)
    .FirstOrDefault(p => p.ProductID == productId);

And you can display your reviews in your view:
HTML
@HTML.DisplayFor(model => model.ProductName)

<p>Reviews:</p>
<ul>
@foreach (var review in model.Reviews)
{
    <li>@HTML.Partial("_Review", review)</li>
}
</ul>
 
Share this answer
 
v2
Comments
Barcelonista Naser 18-Feb-16 13:18pm    
Can't get .Include after repository.products
Richard Deeming 18-Feb-16 13:23pm    
Right, so you're not using Entity Framework.

As I said, you'll need to tell us what you are using, and show us the relevant parts of your code.

Don't try to post it in a comment; click "Improve question" and add the code to your question.
Barcelonista Naser 18-Feb-16 13:34pm    
Richard just look at updated question.
Richard Deeming 18-Feb-16 13:37pm    
You haven't defined a relationship between the Product and Review classes:
Entity Framework - Relationships and Navigation Properties[^]

Also, you haven't shown the code for the repository class.
Barcelonista Naser 18-Feb-16 13:43pm    
Richard, See update question please. I defined the relationship in the back end, Sql Server.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900