要理解我的意思,最好的例子是MVC上的 ASP.NET 一个简单的"MyBlog"。我有来自表作者,帖子和评论的数据库。如果我需要将某些帖子传递到视图中并显示其作者和所有评论,最佳做法是什么?使用EntityFramework延迟加载或创建包含所有必要数据的ViewModel?
还有一个问题要问我:如果是 ViewModel,我应该为每个视图使用它,还是只为需要一些额外数据的地方创建?或者也许我不明白使用 ViewModel 的想法?
提前感谢您的部分体验:)
您应该始终(几乎总是)对不同的操作使用不同的ViewModels
(即使ViewModel
描述相同的Entity
)。事实证明,您不需要在所有操作中获取有关Entity
的所有信息。假设您的Post
实体包含: ICollection<Comment>
- 当您的视图不显示注释(或查询不需要的字段)时,您真的需要获取注释吗?
您还询问了创建ViewModels
的目的是什么 - 这是将数据返回到View
的常见和标准方法。返回适当的填充ViewModel
而不是数据库Entity
将防止Lazy Load
异常和错误。即使您超出数据库范围,您的视图也可能访问延迟加载的字段(因为您的数据库查询可能尚未加载该字段 - 因为您不需要它)。
使用 ViewModel
而不是数据模型Entity
对象的另一个原因是有时需要格式化数据库中的数据以显示(例如,具有正确日期格式的字符串属性而不是 DateTime - string CreatedDate { get; set; }
)。你当然不想让你的Entity
课膨胀。
顺便说一下:我建议您查看AutoMapper库,它可以帮助您自动将属性从Entity
"复制到ViewModel
,而不是手动执行此操作。
我会给你我对事物的"看法"。视图模型,您几乎用于所有视图。不要偷懒,这样做。
因此,创建 ViewModel,用您需要的变量填充它,然后在控制器中填充变量。
稍后,当您开始使用AutoMapper或类似的改进时,您将了解原因。
至于你最初的问题:
class PostViewModel
{
public string Author { get; set; }
public List<Post> Posts { get; set; }
}
这是否有帮助,或者我需要更详细地介绍?
顺便说一句,我不使用延迟加载。我使用它,但 99% 的时间我调用 Include() 以确保我有数据。
您绝对应该使用 ViewModel 来分隔上下文,正如 MVC 模式所暗示的那样。在您的方案中,我可能会使用我计划在各种视图中使用的所有属性的总和来执行功能齐全的 ViewModel,并使用 DbContext 的实体项中的相应值仅填充每个特定视图所需的属性。
下面是一个简短的示例:
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 功能与您的场景并不真正相关,因为您很可能希望在需要时 Load() 或 Include() 您的属性,而当您不需要它们时,请避免使用它们。
有关启用、禁用和有效使用 LazyLoading 功能的快速参考指南,我建议您参考以下参考:
- https://msdn.microsoft.com/en-us/data/jj574232.aspx(MSDN 官方文章)
- http://www.ryadel.com/2015/03/25/enable-or-disable-lazyloading-in-entity-framework/(我在博客上写的一篇文章)
你问的是两个不同的概念。 实体框架是在SQL样式数据库上运行的ORM(对象关系映射)层。 ViewModel 是一个体系结构概念,它使用一个对象,其中包含与当前视图相关的所有数据和行为。 你真的没有理由选择一个或另一个,两者都可能与你正在做的事情相关。
是否正在从数据库加载对象? 这些是使用实体框架完成的(通常使用延迟加载,它真的不会买到太多东西,并且可能会花费您更多的数据库调用)。
当需要向用户呈现数据时,它应该在视图模型中。 该模型是传递给视图的内容。 它应包括与该视图相关的任何内容(用户、页面、相关记录数、可能来自其他源的其他一些信息),并且通常可以包含实体框架中实体的副本。
除非您正在执行 CRUD(创建、检索、更新、删除)视图,否则您的视图和实体之间将存在断开连接,而这种断开连接就是视图模型的用武之地。 一个做得好的MVC应用程序实际上更接近MVVMC(模型视图VewiModel Controller),控制器选择一个ViewModel并告诉它需要知道什么才能与模型通信并获取其数据。 然后将该视图模型传递给视图。 因此,控制器只不过是应用程序的路由器。