ASP.NET MVC EntityFramework lazy loading or ViewModel?
Asked Answered
G

4

6

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 :)

Grooms answered 1/2, 2015 at 20:40 Comment(0)
B
5

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.

Brunhild answered 1/2, 2015 at 21:1 Comment(2)
If I should put all additional information into ViewModel, what for do I need ViewBag?Grooms
@Grooms Honestly - you shouldn't use it at all. If you design proper ViewModel - there wouldn't be need for a ViewBag.Brunhild
I
3

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:

Inna answered 25/3, 2015 at 14:33 Comment(0)
K
2

I'll give you my "View" of things. ViewModel you use for pretty much all every View. Don't be lazy and do it like this.

So create ViewModel, populate it with variables that you need and in Controller populate the variables.

Later, when you start using AutoMapper or similar advancments, you'll understand why.

As to your original question:

class PostViewModel
{
    public string Author { get; set; }

    public List<Post> Posts { get; set; }
}

Did this help or do I need to go in more details?

And by the way, I don't use Lazy loading. I use it, but 99% of time i call Include() to be sure that I have the data.

Kabyle answered 1/2, 2015 at 20:51 Comment(2)
But if to populate ViewModel in Controller, it won't be thin.Grooms
that is why later u'll use AutoMapper and Ninject and so on. I started using them few months back, so I understand you. For now make it work, later you will make it prettier and ...Kabyle
W
2

You're asking about two separate concepts. Entity framework is an ORM (Object Relational Mapping) layer that runs on a SQL style database. ViewModel is an architecture concept that uses an object which contains all data and behavior relevant to the current view. There is really no reason why you should pick one or the other, both are likely to be relevant to what you're doing.

Are you loading objects from a database? Those are done with Entity Framework (usually with lazy loading off, it really doesn't buy you much and can cost you in more database calls).

When the time comes to present your data to your user, it should be in a view model. That model is what is passed to the view. It should include anything relevant to that view (user, page, number of records relevant, some other information that might have come from another source) and can often include a copy of the entity from the Entity Framework.

Unless you are doing CRUD (Create, Retrieve, Update, Delete) views, there is going to be a disconnect between your view and your entity, and this disconnect is where a view model comes in. A well done MVC app is actually closer to MVVMC (Model View VewiModel Controller) where the Controller selects a ViewModel and tells it what it needs to know to talk to the Model and get it's data. That ViewModel is then passed to the View. Thus the Controller becomes little more than a router for your application.

Wareroom answered 1/2, 2015 at 20:55 Comment(2)
Lazy load is useful technique and shouldn't be disabled just because of "fear of more database calls". It will cost more database calls only if not used properly.Brunhild
@Brunhild the problem is that enabling or disabling lazy load is not well understood. The typical overhead in a SQL request is not in the data access (though it can be on occasion) but in the network stack and wires. Does that mean there aren't useful cases for Lazy Loading? No, but it doesn't apply most of the time.Wareroom

© 2022 - 2024 — McMap. All rights reserved.