I'm following Microsoft's ASP.NET MVC tutorial, and as part of it, I generated CRUD operations for the model Movie through scaffolding.
The Index view has the following line at the top:
@model IEnumerable<MvcMovie.Models.Movie>
And the controller passes that object by converting DbSet<MvcMovie.Models.Movie>
of its DbContext
to a List first:
public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}
The tutorial confirms this is intended behavior:
Examine the Index.cshtml view and the Index method in the Movies controller. Notice how the code creates a List object when it calls the View method. The code passes this Movies list from the Index action method to the view:
However, looking at the DbSet
class, it implements IEnumerable<TEntity>
, and in this case, TEntity
is the Movie object. So, why bother converting it to a List?
I tested this by passing _context.Movie
as-is, and it seems to work perfectly fine.
Is there a reason this is done, then?
CodePudding user response:
I tested this by passing _context.Movie as-is, and it seems to work perfectly fine.
It seems to work perfectly fine, and in the most extremely simple cases, it might even work. However:
The View
method needs to iterate through the data that you pass in. In the case of a DbSet<T>
, this means that the entire database table will be SELECT
ed synchronously. There are tons of posts/etc about the difference between synchronous and asynchronous operations including database calls, so I won't go deeper into the details other than saying: in most cases, synchronous usage of Entity Framework Core must be avoided.
This means that, in order to ensure the asynchronous execution of the query, one of the asynchronous query executors must be used, ToListAsync
being a common choice, although ToArrayAsync
would work just as fine for this purpose.
That's the first part. The second part is that, since you are returning a reference to DbSet<T>
, the data is not in memory yet, so an open connection to the database is required until some point in time when the query is executed. Another problem is that the query might end up being executed multiple times, depending on the implementation of whatever takes care of sending the result back to the client.