Имеет ли Dapper IEnumerable‹T› отложенное или немедленное выполнение?

Когда я выполняю запрос в Dapper и хочу получить только блок записей, могу ли я использовать .Skip().Take() или мне нужно использовать select top n * в SQL?

Например, дана таблица с 10 000 записей, и мне нужны только первые 200, потому что моя страница со списком показывает только 200 на странице. Я запускаю это?

conn.Query<Widget>("select * from Widgets").Skip((page - 1) * size).Take(size);

Или это:

conn.Query<Widget>("select top 200 * from Widgets");

Является ли метод Dapper .Query<T> отложенным или нет?


person JK.    schedule 19.10.2013    source источник


Ответы (1)


Вы должны использовать SELECT TOP n....

Метод Query<T> имеет необязательный параметр bool buffered = true, который при значении true перебирает весь набор результатов, считывая каждую строку в List<T>. Вы можете сделать этот параметр ложным, и результирующий IEnumerable<T> будет "отложен" в том смысле, что запрос БД не будет выполняться до тех пор, пока вы его не используете, и строки будут извлекаться со стороны БД "по одной за раз" (вызовы IDataReader.Read на каждой итерации).

Так что да, можно "отложить". ОДНАКО вам все равно следует использовать TOP n, потому что в противном случае вы все равно будете выполнять и подготавливать набор результатов для 10000 записей на стороне базы данных, хотя вы можете передавать клиенту только первые n строк из них.

person Eren Ersönmez    schedule 19.10.2013
comment
Когда для буфера установлено значение false, вам нужно беспокоиться о соединении. Если вы закроете его до ToList (или рекомендуемого AtList), произойдет сбой с ошибкой. - person JustLooking; 01.08.2019