0

I have defined a model, Item, which has the following properties:

public class Item
{
    public bool Active { get; set; }
    public string ItemCode { get; set; }

    public int ItemId { get; set; }
    public string Name { get; set; }

    public Category Category { get; set; }
    public int CategoryId { get; set; }

}

I am trying to reference the Category from within the detail view on the Item controller. My code in the controller is:

public ActionResult Details(int id = 0)
{
    Item item = db.Items.Find(id);
    if (item == null)
    {
        return HttpNotFound();
    }
    return View(item);
}

However, when I explore the item object here I can see the CategoryId is correctly set, the Category property is set to null. Therefore when I reference Item.Category.Name I am getting a blank result. I have tried making my properties virtual (following a tutorial on-line) but this didn't seem to fix the issue. What am I doing wrong?

alexmac
  • 19,087
  • 7
  • 58
  • 69
Joseph
  • 2,706
  • 6
  • 42
  • 80
  • Did you use EF? otherwise show us your repository code. – reptildarat Dec 28 '13 at 14:16
  • You need to include your Category obejct. db.Items.Include(e => e.Category).Find(id); http://stackoverflow.com/questions/7348663/c-sharp-entity-framework-how-can-i-combine-a-find-and-include-on-a-model-obje – David Dec 28 '13 at 14:18
  • is Item class generated by template or you have created it ? – Ankush Jain Dec 28 '13 at 14:38

1 Answers1

2

You can lazy-load the property by marking Category as virtual:

public virtual Category Category { get; set; }

This will fire another query to the data store asking for the related category as soon as you access the Category property. item.Category.Name for example.

Or you can eager-load the category by using the Include method:

Item item = db.Items
              .Include(item => item.Category)
              .FirstOrDefault(item => item.ID == id);

This will retrieve the item including the related category from the data store in 1 query. Notice I used FirstOrDefault here in stead of Find, since the return type of Include is IQueryable<T> and not DbSet<T>.

See this article for more info about loading related data.

Henk Mollema
  • 44,194
  • 12
  • 93
  • 104