views:

66

answers:

2

In an MVC view, I'm looking for a way to determine if a parent entity's collection of child entities is empty, so I can decide if I need to call a RenderPartial() or not.

For a one-to-one I've been using the following:

<% if (Model.Book.GenreReference.EntityKey != null) %>
     {.....}

but I'm unsure how to do it in a one-to-many scenario, or if it can even be done without the use of Include() or Load().

A: 

First of all, you really should have all the data loaded from the DB by the time your model is passed on to the view. Given that, you should have used Include in your query (or Load afterwards) to grab the collection of children in the controller action.

In the view you then do a usual check (something along the lines of):

<% if (Model.Book.Children != null && Model.Book.Children.Any()) %>

(Instead of Children you actually use the navigation property you have - could be Authors for example).

Yakimych
Thanks Yakimych, but I was hoping to avoid loading the collection if I wouldn't need it.
PolishedTurd
+1  A: 

Write a view model:

public class BookPresentation
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public bool HasOrders { get; set; }
    public int ReviewCount { get; set; }
}

Then project onto it:

var model = from b in db.Books
            where b.Id == id
            select new BookPresentation
            {
                Id = b.Id,
                Title = b.Title,
                HasOrders = b.Orders.Any(),
                ReviewCount = b.Reviews.Count()
            };
Craig Stuntz
Jolly good. I like this. Is it unusual that I don't want to load a particular collection unless I have to, as the other answerer alluded to?
PolishedTurd
I don't think so. Comments like "you really should have all the data loaded from the DB by the time your model is passed on to the view" occasionally mean "I'm not sure how to dispose of my `ObjectContext` at a convenient time for this," which is a different matter entirely.
Craig Stuntz
What was actually implied is that it's not a good practice to query the database from within the view (I think you would agree with this).
Yakimych
@Yakimych, I agree with that as stated, but don't think it's the same thing as deferred execution. Deferred execution is fine, I think.
Craig Stuntz
Absolutely. But I think it's pretty important to load the collection in the controller action after knowing that it's not empty (`if (model.HasOrders)` in this case). The view will get all the data required and just present it without executing extra fetching logic.
Yakimych
@Yakimych, no logic is required here. Simply iterating the results -- which the view has to do, regardless -- does all that is required. That's part of the magic of a projection; you never have to think about loading strategies.
Craig Stuntz