设计使用的ViewModels一个MVC库 [英] Designing an MVC repository using ViewModels

查看:159
本文介绍了设计使用的ViewModels一个MVC库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个存储库类从我的控制器分离出我的数据的逻辑。我使用一个ViewModel重新present一些数据,将充满了来自不同表的数据。

这里有一些问题我有:


  1. 对于像 GETALL(),我返回的IQueryable℃的方法; MyViewModel> 的IQueryable<实体GT; ?如果我返回的ViewModels,我怎么应付一个 GETALL(),拉几千条记录?

  2. 请我创建我的自定义ViewModel类的构造,是以实体为参数做映射? (我还没有熟悉automapper所以只需要关于如何从设计的角度来看做到这一点的理解)

此外,我主要关注的是像 GETALL的方法()这将拉动多条记录。如果我做了一个foreach循环每个实体转换成视图模型似乎是一个很大的开销。我的想法是把一个参考自定义视图模型类中的的IQueryable<实体> 从集合访问,并有ListViewModel只是索引或类似的其中提及的东西集合属性。


解决方案

  

1)对于像GETALL()的方法,我返回一个IQueryable或IQueryable的?如果我返回的ViewModels,我怎么用GETALL(),拉几千条记录应付呢?


的IQueryable<实体GT; 。这个仓库不处理视图模型。想想版本库的东西,是在一个单独的类库不引用你的ASP.NET MVC应用程序,它是您的视图模型住在哪里定义的。它是ASP.NET MVC应用程序引用这个库。


  

2)我创建我的自定义ViewModel类的构造,是以实体为参数做映射? (我还没有熟悉automapper所以只需要对如何做到这一点从设计的角度来看的理解)


没有。特别是如果你希望你的控制器动作采取这些视图模型作为操作参数(想到一个POST行为)不要创建您的视图模型的构造。这样做的原因是,默认的模型绑定将不再知道如何实例化视图模型,你将不得不编写自定义模型粘合剂。

所以AutoMapper或手动映射。

与手动映射例子是,你可以下手了什么:

 公众的ActionResult SomeAction()
{
    IEnumerable的<实体GT;实体= Repository.GetAll();
    IEnumerable的< MyViewModel>模型= entities.Select(X =>新建MyViewModel
    {
        为prop1 = x.Prop1,
        Prop2 = x.Prop2,
        ...
    });
    返回查看(模型);
}

一旦你生病了写这篇code移至AutoMapper的:

 公众的ActionResult SomeAction()
{
    IEnumerable的<实体GT;实体= Repository.GetAll();
    IEnumerable的< MyViewModel>模型= Mapper.Map<&IEnumerable的LT;实体>中的IEnumerable< MyViewModel>>(实体);
    返回查看(模型);
}

或者,如果你写一个使用OnActionExecuted事件拉传递给视图的域模型,使用AutoMapper映射到视图模型和视图的视图模型替代模型的自定义行为过滤器,你可以进一步简化重复性code:

  [自动地图(typeof运算(IEnumerable的<实体GT;)的typeof(IEnumerable的< MyViewModel>))]
公众的ActionResult SomeAction()
{
    IEnumerable的<实体GT;实体= Repository.GetAll();
    返回查看(实体);
}


  

此外,我主要关注的是像GETALL()方法,它会拉很多
  记录。如果我做了一个foreach循环每个实体转换成
  视图模型似乎是一个很大的开销。


不要在意这一点。拉你的记录会比循环和映射到视图模型幅度较慢。

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 different tables.

Here are some questions I have:

  1. For a method like GetAll(), do I return an IQueryable<MyViewModel> or IQueryable<Entity>? If I return viewmodels, how do I cope with a GetAll() that pulls thousands of records?
  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)

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. My thought was to put a reference inside the custom ViewModel class to the IQueryable<Entity> to access from the collection, and have the ListViewModel just have indexers or something like that which reference the collection property.

解决方案

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<Entity>. 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<Entity> entities = Repository.GetAll();
    IEnumerable<MyViewModel> 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<Entity> entities = Repository.GetAll();
    IEnumerable<MyViewModel> model = Mapper.Map<IEnumerable<Entity>, IEnumerable<MyViewModel>>(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<Entity>), typeof(IEnumerable<MyViewModel>))]
public ActionResult SomeAction()
{
    IEnumerable<Entity> 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.

这篇关于设计使用的ViewModels一个MVC库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆