tags:

views:

38

answers:

2

I am creating this MVC model and trying to understand best way to do it.How should I get related data when I have relationships between tables.For example in code below I have created a formviewmodel and I am calling function to get all images in Images table for a user. Should I instead keep images property of Users model and fill that within LINQ query in repository instead of calling a method from the Model? Is there a way in LINQ to autofill all images for the contact?

public class UserFormViewModel {

    UucsrRepository repository = new UucsrRepository();

    public User User { get; set; }
    public SelectList States { get; private set; }
    public SelectList Genders { get; private set; }
    public List<Images> UserImages { get; set; }

    public UserFormViewModel(User User) {
        User = User;
        UserImages = repository.GetUserImages(User.Id).ToList();
        States = new SelectList(repository.GetAllStates(), "ShortName", "Name");
        Genders = new SelectList(repository.GetAllGenders(), "Gender", "Description");

    }
}

Thanks !

+1  A: 

First it typically does not make sense to store the actual repository object in the viewmodel. That violates the tenent that you should only send the view exactly what it needs and nothing more. They way i typically create the viewmodels is to ahve a very basic wrapper with almost no code in it. Most of the logic to fill the VM is done in the controller using the repository pattern.

Your example is clear enough to understand how you should or should not be using view models.

Kevin Koenig
A: 

Kevin correctly noted, that the ViewModel should only contain the data you use in the view for presentational purposes. In your case, depending on what the view does, you might only send a subset of your User properties. For example, if you just show some user information, but not modify it, you don't need to send the user ID. I would go with smth like:

public class UserFormViewModel
{
    public string UserName { get; set; }
    public string Email { get; set; }
    ...
    public SelectList States { get; private set; }
    public SelectList Genders { get; private set; }
    public List<Images> UserImages { get; set; }
}

To populate (prepare) the ViewModel it's rather convenient to use a separate helper method:

private UserFormViewModel PopulateUserFormViewModel(int userId)
{
    var model = new UserFormViewModel();
    var user = repository.GetUser(userId);

    model.UserName = user.Name;
    model.Email = user.Email;
    ...
    model.UserImages = repository.GetUserImages(userId).ToList();
    ...

    return model;
}

And in your action you call:

public ActionResult ShowUser(int userId)
{
    // maybe do something else

    var userFormViewModel = PopulateUserFormViewModel(userId);
    return View(userFormViewModel);
}

That's just one of the possible ways, but the general principles are pretty clear: keep your ViewModel simple (just the data you need in the view) and preferably create a reusable method for converting your domain object into your ViewModel.

Yakimych