Я смотрю на SQL, сгенерированный при выполнении простых запросов на выборку. Сначала я использую код с примером контекста блога от nuget.
Если выполняется следующее:
BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();
Создается следующий SQL:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Comments] AS [Extent1]
) AS [GroupBy1]
Где подсчет выполняется в ожидаемом SQL.
Однако, если я изменю код, чтобы он выглядел так:
BlogContext _context = new BlogContext();
var comments = _context.Comments.Select(c => new CommentReadOnly {Author = c.Author});
var count = comments.Count();
private CommentReadOnly ToCommentReadOnly(Comment comment)
{
return new CommentReadOnly
{
Author = comment.Author,
};
}
Создается следующий SQL:
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[PostID] AS [PostID],
[Extent1].[Text] AS [Text],
[Extent1].[Author] AS [Author]
FROM [dbo].[Comments] AS [Extent1]
С кодом count
, выполненным в коде.
Причина (я думаю) в том, что первое возвращается как IQueryable
, где вторым является IEnumerable
.
Можно ли вернуть второй запрос как IQueryable без выполнения SQL?
Причина, по которой я спрашиваю, заключается в том, что я создаю общий слой репозитория, который может запрашивать мои сущности и преобразовывать их в требуемый тип (в приведенном выше примере комментарий может содержать несколько разных «только для чтения» объектов). Я не хочу, чтобы SQL выполнялся так рано, поскольку может выполняться подкачка страниц или другая фильтрация в других ситуациях.