views:

37

answers:

2

I am creating a store with ASP.NET 4.0 MVC and C# and am fairly new to it.

I have come to creating the View page that displays the products within a certain category.

On the specific category page I want to have the product list and also want the category name with its relevant description taken from the database.

Currently the way I have done this is to have two methods in my Repository:

  1. Retrieve the list of products for a specific category with a string
  2. Retrieve the specific category with a string

I then use both these in one ActionResult and then pass them to the view.

Is there a way that I can retrieve both the product list and category name, description etc from 1 method call to the database or have i done it correctly?

Thank you for any help in advance.

My code is as follows:

StoreRepository

public class StoreRepository : topsports.Models.IStoreRepository
{
    private topsportsEntities db = new topsportsEntities();

    public IQueryable<Product> FindProductsByCategory(string c)
    {
        var products = from p in db.Products
                       where p.Category.Name == c
                       select p;

        return products;
    }

    public Category FindCategory(string c)
    {
        return db.Categories.SingleOrDefault(cg => cg.Name == c);

    }
}

IStoreRepository

public interface IStoreRepository
{
    IQueryable<Product> FindProductsByCategory(string c);
    Category FindCategory(string c);

}

StoreController

 public class StoreController : Controller
{
    IStoreRepository storeRepository;

    public StoreController()
        : this(new StoreRepository())
    {
    }
    public StoreController(IStoreRepository repository)
    {
        storeRepository = repository;
    }

    public ActionResult Index(string c)
    {
        var category = storeRepository.FindCategory(c);

        var products = storeRepository.FindProductsByCategory(c).ToList();

        var viewModel = new StoreViewModel
        {
            Products = products,
            Category = category

        };

        return View(viewModel);
    }
}

StoreViewModel

public class StoreViewModel
{
    public List<Product> Products { get; set; }
    public Category Category { get; set; }

}

Category.aspx

<h2><%: Model.Category.Name %></h2>

<p><%: Model.Category.Description %></p>


<ul>
    <% foreach (var item in Model.Products) { %>
        <li>
            <%: item.Name %>, 
            <strong><%: item.Description %></strong>
        </li>
    <%} %>
</ul>
A: 

It might seem like you don't need to get the Category object separately, since you could reference it from one of the items. However, I think it could be good to do it like you have because, for instance, your method will cover the case where a Category does not have any items in it at the moment, for whatever reason.

Andrew Barber
A: 

The purpose of repositories is to decouple your data access layer from your business logic. When you choose to retrieve products through the category entity, you're depending on lazy loading which is an implementation detail of the entity framework. When you would e.g. later on decide to switch to a different data access layer (hand created queries e.g.), it could be you would not have this facility anymore.

A second issue is that when you put a lot of functionality into a single repository method, it becomes unclear what the responsibility of this method is. As @Andrew Barber describes, yes, you will get a lot of small methods. These can then be combined to produce useful functionality. When you would choose to create bigger methods that return more results, you get another problem. When the method that returns e.g. three or four data sets, you get the issues that when you need only on or two of two of these data sets, you either are going to create a new method which does less as the original one, or you are going to run four queries where one or two would have been enough.

The small methods of the repository are meant to produce meaningful results when composed in a larger whole. Many methods is not necessarily a problem. Your code looks fine :).

Pieter
Thanks for your detailed response to my question cleared a few things up for me.