2015-10-22 2 views
1

У меня есть следующий SQL и результат:Фильтрация по простой дате SQL для синтаксиса Linq

SELECT EventTime FROM Incidents 
-- RESULT -- 
2015-10-20 00:00:00.000 
2015-10-20 05:00:00.000 
2015-10-20 05:50:00.000 
2015-10-20 07:00:00.000 
2015-10-20 09:00:30.000 
2015-10-21 05:00:00.000 
2015-10-21 06:10:00.000 
2015-10-22 09:10:00.000 

Я использую следующий SQL для фильтрации обычной даты (SQL 2014):

SELECT DISTINCT CONVERT (Date, [EventTime]) AS EventDate FROM Incidents 
-- RESULT -- 
EventDate 
2015-10-20 
2015-10-21 
2015-10-22 

Так очень простой в SQL. Для LINQ Я пытаюсь логику:

var q = db.TimeLines.Select(x => x.Time.Date).Distinct(); 
// show it 
q.ToList().ForEach(x => { Console.WriteLine("EventDate: {0}", x); }); 

порывает с: Дополнительная информация: Указанный элемент типа «Date» не поддерживается в LINQ ...

... Как написать второй SQL в LINQ ?

+0

Вы используете LINQ to SQL или Entity Framework? –

+0

Для LINQ-to-SQL см. [This] (http://stackoverflow.com/questions/11663523/using-built-in-sql-functions-in-a-linq-query). Для платформы Entity Framework см. [This] (http://stackoverflow.com/questions/12412231/how-do-i-perform-date-part-comparison-in-ef). –

+0

Проверьте [EntityFunctions.TruncateTime] (https://msdn.microsoft.com/en-us/library/dd395596 (v = vs.110) .aspx) – juharr

ответ

1

Если вы изменили запрос в списке перед использованием операторов, которые не могут быть переведены в sql, тогда он будет работать.

var q = db.TimeLines.ToList.Select(x => x.Time.Date).Distinct(); 
// show it 
q.ForEach(x => { Console.WriteLine("EventDate: {0}", x); }); 

Но вам нужно указать в качестве списка, прежде чем вы получите дату на дату, а не после.

EDIT:

В этом случае, я не уверен, что вы получите какое-либо увеличение производительности на всех, но, как упоминалось в комментарии ниже по juharr, используйте AsEnumerable, если вы хотите, чтобы запрос остаться ленивым ,

var q = db.TimeLines.AsEnumerable.Select(x => x.Time.Date).Distinct(); 

EDIT 2:

Если вы хотите, чтобы выполнить запрос полностью на сервере SQL, вы можете использовать DbFunctions.TruncateTime как переводимая функция:

var q = db.TimeLines.Select(x => DbFunctions.TruncateTime(x.Time)).Distinct(); 

EDIT 3: Кроме того, Сергей прав о моем первом примере, вы должны выбрать именно то, что хотите, прежде чем вбрасывать в память, если это делается так:

var q = db.TimeLines.Select(x => x.Time).AsEnumerable.Select(x => x.Date).Distinct(); 
+1

Вы также можете использовать 'AsEnumerable', так что запрос не запускается до тех пор, пока не будет выполнен повторный вывод' IEnumerable'. – juharr

+0

означает? var q = db.TimeLines.AsEnumerable(). Выберите (x => x.Time.Date) .Distinct(); – harveyt

+0

Демпинг целых данных в память - не самая лучшая идея –