简体   繁体   English

使用多个模型比使用ASP.NET MVC中的ViewModel有更好的方法吗?

[英]Is there a better way to consume multiple Models than through ViewModels in ASP.NET MVC?

I'm new working with ASP.NET MVC 2 and one of the examples I'm following is the official ASP.NET MVC Music Store on codeplex. 我正在使用ASP.NET MVC 2,我正在遵循的一个例子 codeplex上的官方ASP.NET MVC音乐商店

In the example project they have this scenario: There are three models: Albums , Artists , Genres . 在示例项目中,他们有这样的场景:有三种模式: AlbumsArtistsGenres

What is making me doubt is the way they treat their views, for example, when they want to edit an album it's needed to have the list of all artists and genres from the database, so they make a ViewModel called StoreManagerViewModel : 让我怀疑的是他们对待他们观点的方式,例如,当他们想要编辑一张专辑时,需要拥有数据库中所有艺术家和流派的列表,因此他们创建一个名为StoreManagerViewModel的ViewModel:

public class StoreManagerViewModel{
  public Album Album{get;set;}
  public List<Artists> Artists{get;set;}
  public List<Genre> Genres{get;set;}
}

This ViewModel is passed to the view, and allows intellisense and to see multiple models in the view. 此ViewModel传递给视图,并允许智能感知并在视图中查看多个模型。

This method seems like it would make me have a extra class for almost every relation in my model: If I have aa Discography class and I want to relate Artists to Discography, I would have to make another ViewModel like the above. 这个方法似乎让我在我的模型中几乎每个关系都有一个额外的类:如果我有一个Discography类,我想将艺术家与唱片相关联,我将不得不像上面那样制作另一个ViewModel。

However, I don't like to have two properties inside the Album Method: 但是,我不喜欢在Album Method中有两个属性:

public List<Artists> Artists{get;set;}
public List<Genre> Genres{get;set;}

Is there a better way of doing this other than ViewModels? 除了ViewModels之外,还有更好的方法吗? Is there a cleaner way? 有更干净的方式吗?

All of the other answers on this page so far have left out one important concept of a view model, that it separates the data layer from the presentation layer, and removes the ability for the view to construct queries which could crush your db. 到目前为止,此页面上的所有其他答案都遗漏了视图模型的一个重要概念,它将数据层与表示层分开,并消除了视图构建可能破坏数据库的查询的能力。 Its not just about intellisense and sending multiple models to the view, although those are other pluses. 它不仅仅是智能感知和向视图发送多个模型,尽管这些是其他优点。

Say for instance you want to load up on your site the top 100 stack overflow users whose name starts with myNamePrefix . 比如说你想在你的网站上加载名称以myNamePrefix开头的前100名堆栈溢出用户。 Then for each user you want to display a list of the tags in for which they have more than 10 upvotes for. 然后为每个用户显示一个标签列表,其中包含10个以上的upvotes。 You could just pass a list of Users to your view, and then call the .Tags property, which would then make a round trip to the db for each of your 100 users. 可以Users列表传递给您的视图,然后调用.Tags属性,然后为100个用户中的每个用户进行数据包往返。 This might be fine when the db resides on the same machine as the web server and you're only getting a few hits per day. 当db与Web服务器位于同一台计算机上并且您每天只获得几次点击时,这可能没问题。 But lets say you you're trying to serve up this data for various values of myNamePrefix every second. 但是,让我们假设您myNamePrefix都尝试为myNamePrefix各种值提供此数据。 You could probably find some creative ways to cache results, but for the most part, its better to populate your view model with all the data it needs (in this case via a single query), and just have the view spit out the results. 您可能会找到一些缓存结果的创造性方法,但在大多数情况下,最好使用所需的所有数据(在这种情况下通过单个查询)填充视图模型,然后让视图吐出结果。 Remember, its the view's job to display the data, not to fetch it. 请记住,视图的作用是显示数据,而不是获取数据。

The reason they choose to create a separate ViewModel instead of using a Model already created such as Albums , Artist , or Genre is because all 3 were required. 他们选择创建单独的ViewModel而不是使用已创建的模型(如AlbumsArtistGenre )的原因是因为所有3都是必需的。 If only one was required such as Albums it would have been fine to transfer just Album or IList<Album> depending on the use. 如果只需要一个,例如Albums ,根据使用情况,只转移AlbumIList<Album>就可以了。

In ASP.NET MVC the Model can be any object in the system that you want to send to the View. 在ASP.NET MVC中,模型可以是系统中要发送到View的任何对象。 Even string , int , and any other base type. 甚至是stringint和任何其他基类型。

In ASP.NET MVC 3 you can also use the dynamic keyword as your ViewModel, so that you don't even have to specify the type. 在ASP.NET MVC 3中,您还可以使用dynamic关键字作为ViewModel,这样您甚至不必指定类型。 However you should probably avoid this until it is a last resort, because it is always better to have a statically typed ViewModel. 但是你应该避免这种情况,直到它成为最后的手段,因为拥有一个静态类型的ViewModel总是更好。

Lastly, you don't have to specify a Model at all, you can set and pull information from the ViewModel dictionary. 最后,您根本不必指定模型,可以从ViewModel字典中设置和提取信息。 But this probably should be avoided for anything more complex than the most simple information, because just like dynamic it isn't statically typed. 但是对于比最简单的信息更复杂的事情,这可能应该避免,因为就像dynamic一样,它不是静态类型的。

The ViewModel is there for two reasons: ViewModel有两个原因:

  1. Intellisense support. 智能感知支持。
  2. Instances where passing a simple model simply isn't enough for your view. 传递简单模型的实例对于您的视图来说是不够的。

The ViewModel allows you to send multiple Models to your view in cases where it makes sense -- there are a lot of cases where one simple Model just doesn't do. ViewModel允许您在有意义的情况下向您的视图发送多个模型 - 在很多情况下,一个简单模型不会这样做。

There are also cases where you only need to send one View to your model. 在某些情况下,您只需要向模型发送一个View。 Use it where it makes sense, and when you only need to send one Model to a view (and you don't care about intellisense) then only send one model to that view. 在有意义的地方使用它,当你只需要向视图发送一个模型(并且你不关心intellisense)时,只需要向该视图发送一个模型。

when you're using Linq to SQL, every model will have its children and parent loaded in the object (when your DB is good). 当你使用Linq to SQL时,每个模型都会在对象中加载子元素和父元素(当你的数据库很好时)。 So in that case the original model is very often all you need in an edit view or a create view. 因此,在这种情况下,原始模型通常是编辑视图或创建视图中所需的全部模型。 because your model will be made for you. 因为你的模型将为你制作。

ViewModels IS the clean way. ViewModels是干净的方式。

the dirty way is using ViewData . 脏的方式是使用ViewData well, 'dirty'. 好吧,'脏'。 if you need a SelectList together with your model, using ViewData is not dirty, it's the best way in those cases. 如果你需要一个SelectList和你的模型,使用ViewData并不脏,这是在这些情况下的最佳方式。

There is another way. 还有另一种方式。 You could use ChildActions. 你可以使用ChildActions。

Child actions can be cached and each child action can be called from multiple views. 可以缓存子操作,并且可以从多个视图调用每个子操作。

Using child actions can be a better solution if you have ViewModels that overlap. 如果ViewModel重叠,则使用子操作可能是更好的解决方案。 For example, if every view has a sidebar, you can render it using childaction, and since it's cached, db wouldn't be queried for sidebar's model. 例如,如果每个视图都有一个侧边栏,您可以使用子操作渲染它,并且由于它被缓存,因此不会查询侧边栏模型的数据库。

This is just another way. 这只是另一种方式。 Wich one is better depends on problem you're trying to solve. 哪一个更好取决于你想要解决的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM