如何正确解析复杂的viewmodel以分离ASP.NET MVC中的域模型?

时间:2016-09-01 20:26:20

标签: c# asp.net-mvc entity-framework automapper

我想知道如何解决以下问题:网站上有一个表单,管理员向Viewmodel输入了大量数据并传递给服务器端。

class CitizenRegistrationViewModel { 
     public string NationalPassportId { get;set; }
     public string Name { get;set; }
     public List<string> PreviousRegisteredOfficeCodes {get;set;}
     // about 30 fields like strings, Booleans, HttpBasedFiles (pdf,jpg).
}

在域中这个数据需要在逻辑上分离并存储在不同的表(EF中的类)中的问题,如 CitizensNationalPassportsTable CitizensWorkingPlaceRecordsTable 等等。 strong>没有复杂类Citizen具有以下属性:

public class Citizen {
    public ICollection<CitizensWorkingPlaceRecords> workingPlaces
    // etc...
}

但是此属性分别存储在不同的表中,其中一对一或一对多关系(此处没有 FK )。唯一 NationalPassportId 属性可用作导航键(每个用户唯一,与不同表中用户相关的所有记录都包含此键)。

我是否应该编写大量代码来将Viewmodel解析为域模型,如:

public void CitizenRegistrationViewModelToDomainModel(CitizenRegistrationViewModel model){
    CitizenNationalPassport passport = new CitizenNationalPassport(model.NationalPassportId);
    CitizensWorkingPlaceRecord workplace = new CitizensWorkingPlaceRecord(model.PreviousRegisteredOfficeCodes, model.NationalPassportId);
     // 12 extra objects need to create...
    db.CitizenNationalPassports.Add(passport);

}

或者有没有更正确的方法来处理这个问题?我想使用AutoMapper,但它是最好的解决方案吗? 我无法改变商业模式&#39;逻辑,因为它是一个遗留项目。

2 个答案:

答案 0 :(得分:1)

您应该有一组表示浏览器与ASP.NET MVC交换的数据的类。让我们为它们命名,例如输入模型。在这些类中,您有元数据属性,自定义属性以及与浏览器和Web服务器之间的交换相关的许多内容。

您应该有另一组表示数据库结构的类,这些类是您的Entity Framework POCO类。让我们将它们命名为DB Models。无论POCO和它们是多么奇特都无关紧要,它们总是映射到表格和列,因此它们总是紧跟数据库结构。

您应该拥有另一组属于您的域类的类,即在业务层中操作对象时使用的类。这些类是绑定/持久性/表示不可知的。

您应该拥有一个知道如何持久保存域实体的存储库。在您的情况下,它将是一个知道如何操作数据库模型和DbContext的类。

  1. 然后,当您从浏览器获得输入时,您将该数据绑定到输入模型,然后将这些数据传递给控制器​​(这由DefaultModelBinder自动完成,或者您可以使用自己的IModelBinder })。
  2. 获得输入模型时,必须使用该数据创建新的域实体(如果是实际的新实体)。准备好域对象后,将其传递到存储库以进行保存。
  3. 存储库负责使用数据库模型了解如何在数据库中保存域实体。
  4. 从本质上讲,您在Controller的操作上下文中运行的Controller或业务服务实例应负责阐明这些元素之间的交互,而无需彼此了解。

答案 1 :(得分:1)

AutoMapper或替代方法可用于自动化从View模型到Domain模型的映射,但这仅在View和Domain模型中命名属性相同时才有意义。如果不是这种情况,您最终会编写对您没有帮助的映射规则。它只是将代码从当前的映射类移动到AutoMapper配置。所以,如果你有能力修改你的视图模型我会去AutoMapper或类似的东西,如果没有我会使用你现在拥有的。