C# 在ASP.NET MVC中,有比通过ViewModels使用多个模型更好的方法吗?
我是ASP.NET MVC 2的新手,也是我在codeplex上关注的示例之一 在示例项目中,他们有这样的场景:有三种模型:C# 在ASP.NET MVC中,有比通过ViewModels使用多个模型更好的方法吗?,c#,asp.net-mvc,viewmodel,C#,Asp.net Mvc,Viewmodel,我是ASP.NET MVC 2的新手,也是我在codeplex上关注的示例之一 在示例项目中,他们有这样的场景:有三种模型:相册,艺术家,流派 让我怀疑的是他们对待视图的方式,例如,当他们想要编辑一张专辑时,需要从数据库中获得所有艺术家和流派的列表,因此他们制作了一个名为StoreManagerViewModel的视图模型: public class StoreManagerViewModel{ public Album Album{get;set;} public List<Ar
相册
,艺术家
,流派
让我怀疑的是他们对待视图的方式,例如,当他们想要编辑一张专辑时,需要从数据库中获得所有艺术家和流派的列表,因此他们制作了一个名为StoreManagerViewModel
的视图模型:
public class StoreManagerViewModel{
public Album Album{get;set;}
public List<Artists> Artists{get;set;}
public List<Genre> Genres{get;set;}
}
公共类StoreManagerViewModel{
公共相册相册{get;set;}
公开列表艺术家{get;set;}
公共列表类型{get;set;}
}
此ViewModel被传递到视图,并允许intellisense和查看视图中的多个模型
这种方法似乎会使我的模型中几乎所有关系都有一个额外的类:
如果我有一个椎间盘造影课程,并且我想将艺术家与椎间盘造影联系起来,我必须制作另一个类似于上面的ViewModel
但是,我不希望在Album方法中有两个属性:
public List<Artists> Artists{get;set;}
public List<Genre> Genres{get;set;}
公开列表艺术家{get;set;}
公共列表类型{get;set;}
除了ViewModels之外,还有更好的方法吗?有更干净的方法吗?有两个原因可以使用ViewModel:
在某些情况下,您只需要向模型发送一个视图。在有意义的地方使用它,当您只需要将一个模型发送到一个视图(而您不关心intellisense)时,则只需将一个模型发送到该视图。当您使用Linq to SQL时,每个模型都将在对象中加载其子对象和父对象(当您的数据库良好时)。因此,在这种情况下,原始模型通常是编辑视图或创建视图中所需的全部。因为你的模型是为你做的
ViewModels
是一种干净的方式
脏方法是使用
ViewData
。嗯,“肮脏”。如果您的模型需要一个SelectList
,那么使用ViewData
不是脏的,这是在这些情况下最好的方法。他们选择创建一个单独的ViewModel
而不是使用已经创建的模型,例如相册
,艺术家
,或者类型
是因为所有3个都是必需的。如果只需要一个,例如相册
,则可以根据使用情况只传输相册
或IList
在ASP.NET MVC中,模型可以是系统中要发送到视图的任何对象。甚至string
、int
和任何其他基类型
在ASP.NET MVC 3中,您还可以使用dynamic
关键字作为ViewModel,这样您甚至不必指定类型。但是,您可能应该避免这种情况,直到万不得已为止,因为使用静态类型的ViewModel总是更好的
最后,您根本不必指定模型,您可以从ViewModel字典中设置和提取信息。但是,对于比最简单的信息更复杂的信息,可能应该避免这种情况,因为就像
动态一样,它不是静态类型的。到目前为止,本页上的所有其他答案都忽略了视图模型的一个重要概念,即它将数据层与表示层分离,并删除视图构造查询的能力,这些查询可能会压碎您的数据库。这不仅仅是智能感知和向视图发送多个模型,尽管这些都是其他优点
例如,假设您希望在站点上加载名称以mynameprifix
开头的前100名堆栈溢出用户。然后,对于每个想要显示标签列表的用户,他们有超过10个以上的投票权。您只需将用户列表
传递给视图,然后调用.Tags
属性,这将为您的100个用户中的每一个用户往返数据库。如果db与web服务器驻留在同一台机器上,并且您每天只收到几次点击,那么这种情况就可以了。但假设您正在尝试每秒为myNamePrefix
的各种值提供这些数据。您可能会找到一些创造性的方法来缓存结果,但在大多数情况下,最好使用视图模型所需的所有数据(在本例中,通过单个查询)填充视图模型,并让视图吐出结果。记住,视图的任务是显示数据,而不是获取数据。还有另一种方法。你可以使用ChildActions
可以缓存子操作,并且可以从多个视图调用每个子操作
如果有重叠的视图模型,则使用子操作可能是更好的解决方案。例如,如果每个视图都有一个侧边栏,您可以使用childaction来呈现它,并且由于它是缓存的,所以不会向db查询侧边栏的模型
这只是另一种方式。哪一个更好取决于您试图解决的问题。我不明白为什么您必须创建另一个视图模型来添加唱片记录信息:您不能只将discography
属性添加到Artist
或将唱片记录字典添加到现有的视图模型吗?这只是因为在编辑唱片集时,您需要将所有相册的列表传递给视图(当然,在相册类中,您拥有该相册当前discography和Artists的属性),我同意您的观点,这就是为什么我试图保持视图的强烈倾斜性,并避免插入到模型类中实际用于特定视图的参数或属性,不是模型或业务逻辑的一部分。我想诀窍是t