ricky89
ricky89

Reputation: 1396

Using Join queries in asp.net MVC

I am following the tutorial for the MVC music store and trying to build upon it. I want to be able to show an image for each item in a category. So far I can return a list of items for a category but am unable to get a URL from the database to populate the image source in my view.

The way I have set my models up is below. I have an item table which contains a foreign key to the Category table. I then have an Image table which has a foreign key to the item table. I have been trying to get a url from the url table for each item returned from the controller.

Category Model: Just a list of Categories

public class Category
{
   public int CategoryId { get; set; }
   public string CategoryName { get; set; }
   public ICollection<Item> Items { get; set; }
 }

Item Model : Contains foreign key to the categories

public class Item
{
    public int ItemId { get; set; }
    public int CategoryId { get; set; }
    public string ItemName { get; set; }

    public virtual Category Category { get; set; }
    public ICollection<Image> Images { get; set; }
}

Image Model : Contains a foreign key to the item table.

public class Image
{
    public int ImageId { get; set; }
    public string ImageURL { get; set; }
    public int ItemId { get; set; }
    public virtual Item Item { get; set; }
}

Browse Controller

public ActionResult Browse(string category)
{
 var categoryModel = storeDB.Categorys.Include("Items")
                     .SingleOrDefault(c => c.CategoryName == category);

 return View(categoryModel);
}

View:

@model Project.Models.Category

<div class="items">
    <h3><em> @Model.CategoryName </em></h3>

        @foreach (var item in Model.Items)
        {
            <a href="@Url.Action("Details",new {id = item.ItemId})"/> @item.ItemName
            <a href="@Url.Action("Details",new {id = item.ItemId})"/> <img alt="@item.ItemName" src= "@item.Image.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault()" />
        }

When I step through the code above, I can see that the Image URL is null, but have been failing to figure out the correct way to set this up. As with any beginner question I imagine Im doing something wrong or missing the obvious. Any help would be welcome.

Thanks

Upvotes: 0

Views: 169

Answers (1)

py3r3str
py3r3str

Reputation: 1879

First of all there is a typo in view @item.Image.Wher... in model is Images (plural). Second, you are trying to display:

<img alt="@item.ItemName" src= "@item.Images.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault()" />

FirstOrDefault() reteruns null or instance of Image neither of them is path to image.

You should check first if object isn't null and url isn't empty and after display Image.ImageURL:

@{var image = item.Images.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault();}
if (image != null && !String.IsNullOrEmpty(image.ImageURL))
{
    <img alt="@item.ItemName" src="@image.ImageURL" />
}   
else
{
    <img alt="@item.ItemName" src="~/default/image/path" />
}

To enable lazy loading, you can use virtual keyword befor ICollection in model:

...
public virtual ICollection<Image> Images { get; set; }
...
public virtual ICollection<Item> Items { get; set; }
...

Does it help?

Upvotes: 3

Related Questions