我正在为我的ASP MVC网络应用创建一些视图模型。 我为数据库创建了“代码优先”模型。这是从数据库模型派生视图模型的好方法吗?
示例数据库模型:
public class Project
{
[Key]
public int Id { get; set; }
public int? CustomerId { get; set; }
public int TypeId { get; set; }
public string Number { get; set; }
public string Name { get; set; }
}
查看型号:
public class ViewModelProject : Project
{
[NotMapped]
public DateTime? Start { get; set; }
[NotMapped]
public DateTime? End { get; set; }
[NotMapped]
public string Manager { get; set; }
}
这是正确的方式还是完全错误?
编辑(子问题): 我有一些非常简单的数据库模型,如ProjectType,它只包含两个属性。我是否还应该在模型视图中对这些模型进行分段,或者我可以这样做: 简单的数据库模型:
public class ProjectType
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int? Code { get; set; }
}
我可以像这样使用它:
public class ProjectVM
{
public string Name { get; set; }
public int Number { get; set; }
public ProjectType Type { get; set; }
}
或者它必须像这样分段:
public class ProjectVM
{
public string Name { get; set; }
public int Number { get; set; }
public string Type { get; set; }
public int TypeCode { get; set; }
}
答案 0 :(得分:3)
我不建议这样做。我(和许多其他人)已经尝试过它并且它不能很好地工作。您将无意中遇到麻烦,因为MVC模型必须根据视图进行定制,而您从DB获得的内容很少适合。当然,你可以把它锤到位,但是代码很快变得混乱,与存储相关,UI代码开始变得混乱。这甚至可以在您的示例中显示,因为您必须将NotMappedAttribute
(与数据存储相关)放到ViewModelProject
(UI级别的类)。
还有许多其他示例可以显示此问题,但是当您想要将模型对象序列化为JSON并将其发送到JavaScript客户端时,我发现这是一个特别好的示例。 JSON序列化程序获取所有公共属性的值,并将它们添加到JSON中。如果要排除属性,则必须使用ScriptIgnoreAttribute
标记它,您还必须将其应用于基类,这会破坏UI与存储相关代码之间的分离。
更好的方法是将staorage模型和MVC模型分开,并将数据从一个映射到另一个(已经存在的预先存在的框架可以帮助您实现这一点,例如Automapper)。这带来了额外的优势,例如更好的可测试性,因为您现在不依赖于特定的数据存储来创建模型实例。