我遵循微软的ASP。. NET MVC教程,作为其中的一部分,我通过脚手架为模型Movie生成了CRUD操作。
Index视图的顶部有以下一行:
@model IEnumerable<MvcMovie.Models.Movie>
控制器通过首先将DbContext
的DbSet<MvcMovie.Models.Movie>
转换为List来传递该对象:
public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}
教程确认这是预期的行为:
检查索引。cshtml视图和Movies控制器中的Index方法。注意代码在调用View方法时如何创建List对象。代码将这个Movies列表从Index操作方法传递给视图:
然而,看看DbSet
类,它实现了IEnumerable<TEntity>
,在本例中,TEntity
是Movie对象。那么,为什么要把它转换成List呢?
我通过按原样传递_context.Movie
进行了测试,它似乎工作得很好。
这样做有什么原因吗?
我通过传递_context来测试这一点。电影是这样的,它似乎工作得很好。
看起来工作得很好,在最简单的情况下,它甚至可以工作。然而:
View
方法需要遍历传入的数据。在DbSet<T>
的情况下,这意味着整个数据库表将被SELECT
编辑为同步。。关于同步和异步操作(包括数据库调用)之间的区别,已经有很多帖子了,所以我不会深入讨论细节,只是说:在大多数情况下,必须避免同步使用实体框架核心。
这意味着,为了确保查询的异步执行,必须使用其中一个异步查询执行器,ToListAsync
是一个常见的选择,尽管ToArrayAsync
也可以很好地用于此目的。
这是第一部分。第二部分是,由于要返回对DbSet<T>
的引用,因此数据尚未在内存中,因此在执行查询的某个时间点之前,需要打开到数据库的连接。另一个问题是,查询最终可能会被执行多次,这取决于将结果发送回客户机的实现。