Designing an MVC repository using ViewModels

前端 未结 3 946
一个人的身影
一个人的身影 2021-02-04 17:25

I want to create a repository class to separate out my data logic from my controllers. I am using a ViewModel to represent some data that will be filled with data from differen

3条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-04 17:40

    1) For a method like GetAll(), do I return an IQueryable or IQueryable? If I return viewmodels, how do I cope with a GetAll() that pulls thousands of records?

    IQueryable. The repository doesn't deal with view models. Think of the repository as something that is defined in a separate class library that doesn't reference your ASP.NET MVC application which is where your view models live. It is the ASP.NET MVC application that references this library.

    2) Do I create a constructor for my custom ViewModel class that takes the Entity as a parameter to do the mapping? (I'm still unfamiliar with automapper so just need an understanding on how to do this from a design point of view)

    No. Don't create constructors in your view models especially if you want your controller actions to take those view models as action parameters (think of a POST action). The reason for this is that the default model binder will no longer know how to instantiate your view model and you will have to write custom model binders.

    So AutoMapper or manually map.

    Example with manual mapping which is what you could start with:

    public ActionResult SomeAction()
    {
        IEnumerable entities = Repository.GetAll();
        IEnumerable model = entities.Select(x => new MyViewModel
        {
            Prop1 = x.Prop1,
            Prop2 = x.Prop2,
            ...
        }); 
        return View(model);
    }
    

    And once you get sick of writing this code move to AutoMapper:

    public ActionResult SomeAction()
    {
        IEnumerable entities = Repository.GetAll();
        IEnumerable model = Mapper.Map, IEnumerable>(entities); 
        return View(model);
    }
    

    or if you write a custom action filter that uses the OnActionExecuted event to pull the domain model that was passed to the view, map it to the view model using AutoMapper and substitute the model with the view model for the view, you could further simplify the repetitive code:

    [AutoMap(typeof(IEnumerable), typeof(IEnumerable))]
    public ActionResult SomeAction()
    {
        IEnumerable entities = Repository.GetAll();
        return View(entities);
    }
    

    Again, my main concern is a method like GetAll() which would pull many records. If I did a foreach loop to translate each Entity into a ViewModel seems like a lot of overhead.

    Don't be concerned about that. Pulling your records will be a magnitude slower than looping and mapping to the view model.

提交回复
热议问题