Loading related object in MVC can be pretty confusing.
There are lots of terms you need to be aware of and learn if you really want to know what you\'re doing when w
I created a test MVC4 internet application.
Here's what I found:
First, create your entity model classes - notice the virtual
keyword for the Manufacturer
property:
public class Manufacturer
{
public int ManufacturerId { get; set; }
public string Name { get; set; }
public ICollection Brands { get; set; }
}
public class Brand
{
public int BrandId { get; set; }
public string Name { get; set; }
public int ManufacturerId { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
Next, create your controller - I created (autogenerated using create new controller dialog) mine with CRUD action methods and views. Notice the Include
extension method that was autogenerated automatically by Visual Studio thanks to the relationship in you Brand
model class.
public class LazyLoadingStoreController : Controller
{
private UsersContext db = new UsersContext();
//
// GET: /LazyLoadingStore/
public ActionResult Index()
{
var brands = db.Brands.Include(b => b.Manufacturer);
return View(brands.ToList());
}
Let's remove the Include
part for now so that our action method looks like this:
public ActionResult Index()
{
var brands = db.Brands;
return View(brands.ToList());
}
And this is how the Index
view will look in Page Inspector after adding a couple of Brand
objects - notice that Visual Studio automatically added the dropdown for Manufacturer
and how it automatically scaffolded the Name
column for Manufacturer
- sweet!:
The Create
action method:
//
// GET: /LazyLoadingStore/Create
public ActionResult Create()
{
ViewBag.ManufacturerId = new SelectList(db.Manufacturers, "ManufacturerId", "Name");
return View();
}
Awesome. Everything was autogenerated for us!
Now, what happens if we remove the virtual
keyword from our Manufacturer
property?
public class Brand
{
public int BrandId { get; set; }
public string Name { get; set; }
public int ManufacturerId { get; set; }
public Manufacturer Manufacturer { get; set; }
}
This is what will happen - our Manufacturer data is gone:
Okay, makes sense. What if I add back the Include
extension method (with virtual
still removed from the Manufacturer
property)?
public ActionResult Index()
{
var brands = db.Brands.Include(b => b.Manufacturer);
return View(brands.ToList());
}
This is the result from adding back the Include
extension method - The Manufacturer
data is back!:
So that's how all that stuff work.
Next thing would be to explain what kind of T-SQL that gets generated behind the scenes in both cases (Lazy loading and Eager loading). That I'll leave to someone else. :)
Note: Visual Studio automatically generates Include(b => b.Manufacturer)
wheather you add the virtual
keyword or not.
Note2: Oh, yeah. Almost forgot. Here are some links to some good Microsoft resources.
The second link talks about performance considerations which the other link lacks if that is something that gets you going.