In Entity Framework Core ToDictionaryAsync
(and of course) also the the synchronous counter part ToDictionary
retrieve the whole object from the database.
ToDictionaryAsync
If you have a look at the definition of ToDictionaryAsync
:
public static Task<Dictionary<TKey, TElement>> ToDictionaryAsync<TSource, TKey, TElement>(
this IQueryable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector,
CancellationToken cancellationToken = default)
where TKey : notnull
=> ToDictionaryAsync(source, keySelector, elementSelector, comparer: null, cancellationToken);
Then we can see it accepts a lambda over an expression aka (Expression<Func<TSource, TKey>>
). That also means, that the evaluation of this is done client-side!
So if you have a query and object as such:
public class BlogPost
{
public int Id { get; set; }
public required string Title { get; set; }
public required string Description { get; set; }
public required string Content { get; set; }
public required string Author { get; set; }
}
And you do something like this:
return await dbContext.BlogPosts
.Where(...)
.ToDictionaryAsync(k => k.Author, v => v.Title) // Could also be useful
Then you are not only retrieving Author
and Title
from the database, but for example also Content
. I came across this ticket that made me realise this! So to come around use Select
as this is evaluated on the server-side:
return await dbContext.BlogPosts
.Where(...)
.Select(s => new { Author = s.Author, Title = s.Title })
.ToDictionaryAsync(k => k.Author, v => v.Title) // Could also be useful