Принципиальное различие между этими двумя случаями состоит в том, что:
- в первом случае LINQ2SQL переводит условие
Where
в SQL и передает его в БД для выполнения фактической фильтрации - во втором случае все записи извлекаются из базы данных, и фильтрация выполняется по списку объектов в памяти
Разница в результатах может быть объяснена, например, усечением, которое может занятьпоместить в SQL, если столбцы Datum
определены как date
вместо datetime
.
Мне удалось воспроизвести проблему следующим образом:
У меня есть таблица, определенная следующим образом:
CREATE TABLE [Event] (
[Id] int identity primary key,
[EventDate] date
)
Я ввел в таблицу следующие данные:
Id EventDate
-- ---------
1 1/17/2012
2 1/18/2012
В C # мои пределы дат определены так:
var startDate = new DateTime(2012, 1, 17);
var endDate = new DateTime(2012, 1, 18).AddMinutes(10);
Имея эту настройку, я теперь делаю:
var events1 = dc.Events
.Where(d => d.EventDate > startDate && d.EventDate < endDate)
.ToList();
foreach (var @event in events1)
Console.WriteLine(@event.EventDate);
, которая возвращает только первую строку (EventDate = 17.01.2012)
И я делаю:
var events2 = dc.Events.ToList();
foreach (var @event in events2
.Where(d => d.EventDate > startDate && d.EventDate < endDate))
Console.WriteLine(@event.EventDate);
, который отображает обе записи .
ДиДело в том, что в первом случае L2S перевел верхний предел даты с datetime
до date
, потому что именно так я определил столбец [EventDate]
.Это теряет часть времени, и '2012-01-18 00:10'
становится '2012-01-18'
.При сравнении с '<' (строго меньше), конечно, запись 2012-01-18 отфильтровывается с помощью SQL. </p>
В другом случае у меня есть даты, как в SQL, но на этот разони фильтруются в памяти по значению endDate
, которое определяется как DateTime
, таким образом, содержит информацию о времени, и условие «строго меньше» становится истинным.