Search code examples
asp.netasp.net-mvcnhibernateasp.net-mvc-2nhprof

NHProf generates 'this statement executed from the view' warning when I pass a ViewModel object to my ASP.NET MVC View page


I just noticed that on one page of my site, where I pass a ViewModel to my View page, NHProf is giving the following warning:

This statement executed from the view, which can result in bad performance and/or brittle behaviour.

It then links to this page: http://nhprof.com/Learn/Alerts/QueriesFromViews

My ViewModel consists of just 2 properties:

public IEnumerable<Photo> Photos { get; set; }
public Photo SelectedPhoto { get; set; }

I assign the photos to this ViewModel within my Controller as follows:

PhotoViewModel myViewModel = new PhotoViewModel();
myViewModel.Photos = entity.Photos;

My View obviously inherits this type, and aside from outputting a header (which makes use of the SelectedPhoto object), it just loops through each of the Photos rendering some content for each of them.

NHProf shows the 'problem' query as being where it retrieves the collection of Photos that I'm looping through in my view, though I'm not explicitly telling it to go off and get those records from within my view - I've passed those records within the Photos property of my ViewModel.

I have other pages where I don't need to pass a ViewModel and I simply pass IEnumerable<Photo> to the View, and then render the markup exactly the same as I do in the problem view, and NHProf gives no warnings (as there shouldn't be) in that scenario.

I'm thinking maybe it's related to Lazy Loading, and because my collection is part of a ViewModel, when I go to loop through the Photos property within the ViewModel type, it goes to get those records at that point?

Does anyone have any idea what is happening here? The site functions perfectly, but NHProf just sees that it's doing something from where it shouldn't be doing it?!


Solution

  • You haven't shown how your Photos collection is being populated, but I assume it's as simple as viewModel.Photos = entity.Photos. If that's correct (or something similar), then you're just assigning the lazy-loaded entity collection to your view model.

    There are several ways to tackle this, but they're all essentially the same: you need to trigger the loading of your collection before you populate your view model. The easiest way to do it is to just stick a .ToArray() or equivalent onto the collection you're assigning; that'll force a fetch.