为包含多个数据库表的视图创建ViewModel(MVC 4)

时间:2015-04-07 17:22:25

标签: c# asp.net-mvc wpf asp.net-mvc-4 mvvm

假设我有三个数据库表:Zoo,Animal和ZooAnimal,它们看起来像这样:

// Zoo //
int ID
string Name

// Animal //
int ID
string Name
string Genus
string Species

// ZooAnimal //
int ID
int ZooID
int AnimalID

我想创建一个View,显示一个包含每个动物园中存在的动物的表,如下所示:

+------------+--------+----------+-----------+
| Zoo        | Animal | Genus    | Species   |
+============+========+==========+===========+
| Oregon Zoo | Lion   | Panthera | P. leo    |
+------------+--------+----------+-----------+
| Oregon Zoo | Tiger  | Panthera | P. tigris |
+------------+--------+----------+-----------+

如果这只是一张桌子,那很简单。一个带有EditorFor或DisplayFor的ViewModel。但是,由于ViewModel中显示的数据跨越多个连接在一起的表,我该如何组织这个?

到目前为止,我已经研究过具有单独的ViewModel和DomainModel类。三个域模型类(用于Zoo,Animal和Animal Zoo)和一个ViewModel类(用于" AnimalsByZoo"视图)。

// AnimalInZoo ViewModel //
string Zoo
string Animal
string Genus
string Species 

我的DomainModel类将由DbContext填充,但是如何使用存储在DomainModel中的值填充我的ViewModel数据?我的ViewModel每个DomainModel需要一个字段吗?

// AnimalInZoo ViewModel //
[same fields as above]
Zoo ZooDomainModel
Animal AnimalDomainModel
ZooAnimal ZooAnimalDomainModel

这似乎是合理的,但是并不违反ViewModels只有要在屏幕上显示的元素的想法?

3 个答案:

答案 0 :(得分:1)

您可以使用Automapper。这是一个非常容易使用的库,允许您映射对象。所以,你只需要:

  1. 安装包

    PM>安装包AutoMapper

  2. 注册映射

    AutoMapper.Mapper.CreateMap(); AutoMapper.Mapper.CreateMap();

  3. 地图

    var objModel = Mapper.Map(objData);

  4. 您可以在http://automapper.org/

    找到更详细的信息

答案 1 :(得分:1)

ViewModels用于表示视图工作所需的数据。您拥有用户创建/编辑/删除或仅显示所需的属性。您还可以通过添加 DataAttributes 来定义这些属性的规则,以便您可以执行model validation。您永远不应该将您的域模型返回到您的视图。

您可以使用一个包含每个域模型所需的所有属性的模型,从而创建 ViewModel 。如果所有这些属性都是简单属性,并且您需要填写所有属性以创建 AnimalsByZoo ,那么这可能是要走的路。如果您只需要显示数据,这也应该足够了。 正如Gabriel所述,您可以使用AutoMapper在DM和VM之间来回映射。

AnimalsByZooVM animalsByZoo = Mapper.Map<AnimalsByZooVM>(dbData);

但是,如果您的视图稍微复杂一些,或者您认为由于某种原因需要将其拆分,则可以创建3个VM。使用3个虚拟机来表示2个表可能会非常强大,因为您可以拥有一个 AnimalVM 和一个 ZooVM 。然后创建一个AnimalZooVM来保存另外两个ViewModel,甚至是出于某种原因需要显示或保留的其他属性。

public class AnimalZooVM
{
    public ICollection<AnimalVM> Animals { get;set; }
    public ICollection<ZooVM> Zoos { get;set; }
    public int ZooAnimalId { get;set; }
}

如果你有这样的ViewModel,你可以使用AutoMapper以这种方式将你的DM映射到你的虚拟机

AnimalZooVM vm = new AnimalZooVM();
vm.Animals = Mapper.Map<AnimalVM>(dbData);
vm.Zoos = Mapper.Map<ZoosVM>(dbData);

答案 2 :(得分:0)

在我看来,最好转换数据,这样你就可以在ViewModel上拥有一个IEnumerable,并且在每个Zoo对象中都有一个IEnumerable。适合展示和使用。