To understand what I mean, the best example to consider is a simple "MyBlog" on ASP.NET MVC. I have database from tables Author, Post and Comment. If I need to pass some Post into view and display it's Author and all Comments, what will be the best practice? using EntityFramework lazy loading or create ViewModel with all necesery data?
And there is also one question for me: if it is ViewModel, shold I use it for every view, or create only for that, where some extra data is needed? or maybe I don't understand the idea of using ViewModel?
Thanks in advance for part of your experience :)
You should always(almost always) use different ViewModels
for different operations (even if ViewModel
describes same Entity
). It turns out you don't need to get all information about Entity
in all operations. Let say your Post
entity contains: ICollection<Comment>
- do you really need to get comments (or query for fields you don't need) when your view doesn't display that?
You also have asked what's the purpose of creating ViewModels
- it's common and standard way for returning data to View
. Returning appropiate filled ViewModel
instead of database Entity
will prevent Lazy Load
exceptions and errors. Your view might access lazily loaded field even if you're out of database scope (because your database query might not have loaded that field - cause you didn't need it).
The other reason of using ViewModel
instead of data-model Entity
objects is that sometimes there is a need to format data from database to display (ex. string property with proper date formatting instead of DateTime - string CreatedDate { get; set; }
). You certainly wouldn't like to bloat your Entity
class with that.
By the way: I suggest you to look at AutoMapper library which helps you to automate "copying" properties from Entity
to ViewModel
instead of doing this by hand.
You should definitely use a ViewModel to separate context, as implied by the MVC pattern. In your scenario, I would probably do a full-featured ViewModel with the sum of all properties I plan to use in the various views, and populate only those I need for each specific view with their corresponding value from the DbContext's Entity items.
Here's a brief example:
public ActionResult Edit(int? id = null)
{
Room r = UnitOfWork.GetContext().Rooms
.Where(i => i.ID == id.Value).FirstOrDefault();
RoomViewModel rvm = new RoomViewModel();
rvm.ID = r.ID;
rvm.Name = rvm.Name;
if (needToBindChildren) rvm.ChildItems = r.ChildItems;
return View(rvm);
}
Other than having your code clean and MVC-compliant, an additional advantage over using a ViewModel is that you'll be able to use it as the main POST parameter for any request you'll eventually need to do (basically, every View featuring an html form):
[HttpPost]
public ActionResult Edit(RoomViewModel rvm)
{
string name = rvm.Name;
int id = rvm.ID;
UpdateRoomName(id, name);
}
You can either manually bind the properties or use a mapper of your choice (EmitMapper, Ninject, AutoMapper etc.), depending on your needs.
The LazyLoading feature isn't really relevant in your scenario, since you'll most likely want to Load() or Include() your properties when you need them and just avoid using them when you don't.
For a quick reference guide about enabling, disabling and effectively using the LazyLoading feature I suggest you the following references: