I know that I can use ToList()
in my Entity Framework queries, in which case all rows are loaded into memory. But, otherwise, when are those rows loaded?
If I have a query that returns many rows, how can I ensure they are not all loaded into memory? (Like a data reader.)
Does someone know where this information is documented more clearly?
CodePudding user response:
Have a look at the Buffering and streaming topic.
Buffering refers to loading all your query results into memory, whereas streaming means that EF hands the application a single result each time, never containing the entire resultset in memory. In principle, the memory requirements of a streaming query are fixed - they are the same whether the query returns 1 row or 1000; a buffering query, on the other hand, requires more memory the more rows are returned. For queries that result large resultsets, this can be an important performance factor.
Whether a query buffers or streams depends on how it is evaluated.
Avoid using
ToList
orToArray
if you intend to use another LINQ operator on the result - this will needlessly buffer all results into memory. UseAsEnumerable
instead.
You might also want to read the Tracking, no-tracking and identity resolution topic.
The below shows an example of a streaming approach.
foreach (var blog in context.Posts
.AsNoTracking() // Or .AsNoTrackingWithIdentityResolution
.Where(p => p.Title.StartsWith("A"))
)
{
// ...
}