У меня есть некоторый linq, который возвращает правильные данные.
var numEmails = (from row in EmailBatchProposal
where row.EmailBatchId == emailBatchId
select row.EmailBatchProposalId).Count();
Однако, если я правильно понимаю linq, это не выполняется оптимально. Он захватывает все данные, а затем просматривает список и подсчитывает строки. Мне бы очень хотелось использовать linq (в фоновом режиме), например:
Select count(*) from ...
Я уверен, что причины производительности очевидны.
Кто-нибудь знает правильный способ сделать это?
На самом деле, если запрос linq используется с коллекцией, которая реализует IQueryable и поддерживает перевод в базовый вариант SQL, это довольно простая функциональность, позволяющая правильно перевести функцию Count из вашего примера.
Вы можете просто использовать аргумент .Count()
.
int numEmails = EmailBatchProposal.Count(x => x.EmailBatchId == emailBatchId)
Как отмечено ниже, это фактически не разрешает какой-либо другой SQL, но я думаю, что это по крайней мере более чистая альтернатива.
Проверьте журнал SQL, используемый в запросе.
using (var dbc = new siteDataContext())
{
dbc.Log = Console.Out;
var bd = (from b in dbc.birthdays
select b).Count();
Console.WriteLine("{0}", bd);
}
дает запрос:
SELECT COUNT(*) AS [value]
FROM [dbo].[birthdays] AS [t0]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
Собственно, LINQ-to-SQL достаточно умен, чтобы знать, что он должен делать подсчет... Например, если у меня есть следующий запрос:
var v = (from u in TblUsers
select u).Count();
SQL, который фактически выполняется, когда я запускаю это:
SELECT COUNT(*) AS [value]
FROM [tblUsers] AS [t0]
Удивительно, а? Другой плакат сделал действительно хорошее предложение получить LinqPad - это ЧУДЕСНЫЙ инструмент. Он покажет вам точный SQL, который будет выполнен. Вы всегда можете подтвердить с помощью профайлера SQL.
Люди обычно лучше всего учатся, практикуя. Я бы предложил вам получить копию LinqPad (бесплатно), ввести в ваш запрос Linq и посмотреть, какой SQL он генерирует. Затем вы можете изменить запрос Linq, пока не получите именно то, что хотите.