要明白我的意思,最好的例子就是一个简单的" MyBlog"在ASP.NET MVC上。我有来自表作者,发布和评论的数据库。如果我需要将一些发布传递到视图中并显示它的作者和所有评论,那么最佳做法是什么?使用 EntityFramework延迟加载或使用所有necesery数据创建 ViewModel ?
还有一个问题要问我: 如果它是 ViewModel ,那么我将它用于每个视图,或仅为此创建,需要一些额外的数据?或者我可能不理解使用ViewModel的想法?
提前感谢您的部分经验:)
答案 0 :(得分:3)
对于不同的操作,您应该(几乎总是)使用不同的ViewModels
(即使ViewModel
描述相同的Entity
)。事实证明,您无需在所有操作中获取有关Entity
的所有信息。假设您的Post
实体包含:ICollection<Comment>
- 当您的视图未显示时,您是否真的需要获取评论(或查询您不需要的字段)?
您还询问了创建ViewModels
的目的是什么 - 这是将数据返回View
的常用和标准方式。返回合适的填充ViewModel
而非数据库Entity
将阻止Lazy Load
例外和错误。即使您的数据库范围不正确,您的视图也可能访问延迟加载的字段(因为您的数据库查询可能没有加载该字段 - 因为您不需要它)。
使用ViewModel
而不是数据模型Entity
对象的另一个原因是,有时需要格式化数据库中的数据以显示(例如,具有正确日期格式而不是DateTime的字符串属性) - string CreatedDate { get; set; }
)。你当然不希望用你的Entity
课程膨胀。
顺便说一下:我建议您查看AutoMapper库,它可以帮助您自动将“{1}}”复制到Entity
,而不是手动执行此操作。
答案 1 :(得分:1)
我会给你我的&#34; View&#34;东西的。几乎所有View都使用的ViewModel。不要懒惰,这样做。
因此,创建ViewModel,使用您需要的变量填充它,并在Controller中填充变量。
稍后,当您开始使用AutoMapper或类似的优点时,您就会明白原因。
关于你原来的问题:
class PostViewModel
{
public string Author { get; set; }
public List<Post> Posts { get; set; }
}
这有帮助还是我需要了解更多细节?
顺便说一句,我没有使用延迟加载。我使用它,但99%的时间我打电话给包含()以确保我有数据。
答案 2 :(得分:1)
您应该使用 ViewModel 来分隔上下文,如MVC模式所暗示的那样。在您的场景中,我可能会使用我计划在各种视图中使用的所有属性的总和来创建一个功能齐全的ViewModel,并且只使用DbContext的Entity项中的相应值填充每个特定视图所需的那些。
以下是一个简短的例子:
public ActionResult Edit(int? id = null)
{
Room r = UnitOfWork.GetContext().Rooms
.Where(i => i.ID == id.Value).FirstOrDefault();
RoomViewModel rvm = new RoomViewModel();
rvm.ID = r.ID;
rvm.Name = rvm.Name;
if (needToBindChildren) rvm.ChildItems = r.ChildItems;
return View(rvm);
}
除了使代码干净且符合MVC之外,使用ViewModel的另一个好处是,您将能够将它用作最终需要执行的任何请求的主POST参数(基本上,每个以 html表单为特色的视图:
[HttpPost]
public ActionResult Edit(RoomViewModel rvm)
{
string name = rvm.Name;
int id = rvm.ID;
UpdateRoomName(id, name);
}
您可以根据需要手动绑定属性或使用您选择的映射器(EmitMapper,Ninject,AutoMapper等)。
LazyLoading 功能在您的方案中并不真正相关,因为您很可能希望加载()或包含()当您需要它们时,您的属性,并在您不需要时避免使用它们。
有关启用,停用和有效使用 LazyLoading 功能的快速参考指南,建议您使用以下参考资料:
答案 3 :(得分:0)
你问的是两个不同的概念。实体框架是一个在SQL样式数据库上运行的ORM(对象关系映射)层。 ViewModel是一种体系结构概念,它使用包含与当前视图相关的所有数据和行为的对象。你真的没有理由选择其中一个,这两个都可能与你正在做的事情有关。
您是从数据库加载对象吗?这些都是使用实体框架完成的(通常延迟加载,它实际上并没有给你带来太多的收益,并且可能会花费你更多的数据库调用)。
当您的数据呈现给用户时,它应该在视图模型中。该模型是传递给视图的模型。它应该包括与该视图相关的任何内容(用户,页面,相关记录的数量,可能来自其他来源的一些其他信息),并且通常可以包含实体框架中的实体副本。
除非您正在进行CRUD(创建,检索,更新,删除)视图,否则将作为视图与实体之间的断开连接,此断开连接是视图模型的来源一个做得好的MVC应用程序实际上更接近MVVMC(模型视图VewiModel控制器),其中Controller选择ViewModel并告诉它需要知道与模型交谈并获取它的数据。然后将ViewModel传递给View。因此,Controller只不过是您应用程序的路由器。