ASP.NET MVC:如何将EF实体用作视图模型?

16

可能重复:
ASP.NET MVC-将Linq to Entities模型用作ViewModel-这是一个好的实践吗?

在ASP.NET MVC中将EF实体类用作视图模型是否可行?

如果视图模型有90%与EF实体类相同怎么办?

假设我有一个Survey类在Entity Framework模型中。它与编辑视图所需的数据匹配90%。 与视图模型应该具有的唯一区别是要在其中使用一些属性(这些属性需要用于填充Survey对象,因为EF类无法直接映射到其属性的表示方式(子复选框,单选按钮组等)。

您是否使用ViewData []传递它们?还是创建一个Survey类的副本(SurveyViewModel),其中包含新的附加属性(它应该能够从Survey复制数据并返回到它)?

编辑: 我也试图避免将Survey用作SurveyViewModel属性。 当使用UpdateModel或默认绑定程序更新某些Survey属性时,而其他属性(无法直接映射到实体的属性)-在控制器中使用SurveViewModel自定义属性时,它会看起来很奇怪。

4个回答

18

我喜欢使用Jimmy Bogard的方法,始终保持视图和视图模型之间的1:1关系。换句话说,我不会将我的领域模型(在这种情况下是EF实体)用作视图模型。如果你觉得在两者之间进行大量映射工作,你可以使用AutoMapper来替你完成这项工作。


2
+1 for Automapper... 刚刚发现它,我很喜欢。 - Martin
1
ValueInjecter要好得多。 - mare
1
Automapper改变了我的生活,它非常有帮助,特别是一旦你习惯了它并学会了映射导航属性。 - JBeagle

16

一些人不喜欢在视图中完全传递这些模型类,尤其是因为它们是与您目前使用的特定ORM相关联的类。 这意味着您将数据框架紧密绑定到视图类型。

但是,在几个简单的MVC应用程序中,我使用EF实体类型作为某些强类型视图的模型 - 这很好用而且非常简单。 有时候,简单胜出,否则您可能会发现自己在将值复制到几乎相同的模型类型之间耗费大量时间和代码,而实际上您永远不会从EF移动。


8
即使是1:1的情况,您也应该始终拥有视图模型。这里我将重点关注实际原因而不是数据库层耦合。
使用域、实体框架、nhibernate或linq 2 sql模型作为您的视图类存在问题,即无法很好地处理上下文验证。例如,给定一个用户类:
当某人在您的网站上注册时,他们会得到一个用户屏幕,然后您需要:
1.验证名称 2.验证电子邮件 3.验证密码是否存在
当管理员编辑用户名时,他们会得到一个用户屏幕,然后您需要:
1.验证名称 2.验证电子邮件
现在通过FluentValidation、DataAnnotations属性甚至是业务类上的自定义IsValid()方法公开上下文验证,并仅验证名称和电子邮件更改。但您不能这样做。您需要将不同的上下文表示为不同的视图模型,因为这些模型上的验证取决于屏幕表示形式。
在MVC 1中,您可以通过简单地不发布不想验证的字段来解决此问题。但在MVC 2中,情况已经改变,现在每个模型的每个部分都会被验证,无论是否发布。
Robert Harvey指出了另一个好处。您的用户Entity Framework如何显示屏幕并验证双重密码匹配?

你说得有道理,但如果你正在进行双重密码输入匹配,那么你的视图模型(View Model)和实体模型(Entity Model)对象并不是真正的一对一关系,是吗? - Robert Harvey
@Robert Harvey,是的,我应该使用不同的例子。验证密码是否存在更好,因为在管理员编辑中,您永远不会更改密码。谢谢,我会更改它。 - John Farrell

0
在大型项目中,我通常会将业务对象与数据对象分开作为一种风格。这是一种更容易让程序和数据库进行更改并仅影响控制(或VM)层的方法。

1
MVC上下文中的视图模型是指专门设计以供MVC视图消费的模型类。它们通常只是一个包含表示域模型子集的属性的类。 - Jace Rhea
感谢您的反馈。我已经好几年没有使用MVC了。我想那只是当时从微软得到的指导和一些类。那部分可能已经与MVVM合并了。 - tzerb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接