Можно ли выполнить запрос с помощью linq для поиска в течение определенного периода времени? - PullRequest
4 голосов
/ 03 апреля 2012

Детали проблемы:

  • SQL Server 2005;
  • Entity Framework 4.0.

Я пытаюсь с помощью linq выполнить запрос только в течение определенного периода времени. Exemple:

У меня на сервере есть следующие datetime данные:

30/03/2012 12:53:22
30/03/2012 17:23:29
04/04/2012 11:10:14
04/04/2012 19:06:55   

Я хочу выполнить запрос, который вернет мне все данные между временем (12:00 и 20:00), и запрос должен вернуть мне следующие данные:

30/03/2012 12:53:22
30/03/2012 17:23:29
04/04/2012 19:06:55  

Или между (11:00 и 13:00) и запросом необходимо вернуть мне следующие данные:

30/03/2012 12:53:22
04/04/2012 11:10:14  

Как я могу сделать это с linq? Можно ли (чтобы игнорировать дату, использовать только время)?

Ответы [ 4 ]

3 голосов
/ 03 апреля 2012
var filteredTimes = myContext.MyTable
   .Where(r => SqlFunctions.DatePart("hour", r.DateField) >= 11 &&
               SqlFunctions.DatePart("hour", r.DateField) <= 13);

Вам нужно включить System.Data.Objects.SqlClient, чтобы получить SqlFunctions.

0 голосов
/ 04 апреля 2012

Если вы конвертируете значение даты в двойное число и используете дробную часть if, вы получите число от 0 до 1, представляющее время в дне.Имея это, тривиально проверить интервалы времени, где, например, 13:45 будет 0,5729166667 (или более точно: 13: 45,345 - 0,572920679).

Вы можете сделать это, потому что EF (т.е.4.3, версия, которую я использую) переводит функции Cast и даже Math в SQL:

mycontext.Data.Where(dt => dt.DateTime.HasValue)
    .Select(dt => dt.DateTime.Value).Cast<double>()
    .Select(d => d -  Math.Floor(d))
    .Where(... your comparisons

Это переводит в Sql, содержащий CAST([date column] AS float) и функцию FLOOR Sql.


Послеваши комментарии:

Это выглядело так просто, но я не могу найти способ, чтобы EF поручил CAST для одного свойства в Select().Только Cast<>() функция переводится в CAST (sql), но она работает на множестве.

Ну, к счастью, есть другой способ:

mycontext.Data.Where(dt => dt.DateTime.HasValue)
.Select(dt => new
    {
      Date = DbFunctions.TruncateTime(dt.DateTime.Value),
      Ms = DbFunctions.DiffMilliseconds(
               DbFunctions.TruncateTime(dt.DateTime.Value), dt.DateTime.Value)
    })
.Where(x => x.Ms > lower && x.Ms < upper)

, где lower и upper являются свойством TotalMilliseconds объектов TimeSpan.

Обратите внимание, что это ужасно неэффективно в sql!Функции даты повторяются для каждого сравнения.Поэтому убедитесь, что вы выполняете сравнения с набором данных, который был максимально ограничен другими критериями.Может быть даже лучше сначала получить данные в память, а затем выполнить сравнение.

Примечание: до EF6 DbFunctions было EntityFunctions.

0 голосов
/ 03 апреля 2012

Если в вашей таблице есть столбцы date и time (как это возможно в SQL Server 2008), вы можете сделать это непосредственно в SQL.

Поскольку это не так, у вас естьсделать это так:

// the first two lines can be omitted, if your bounds are already timespans
var start = startDate.TimeOfDay;
var end = endDate.TimeOfDay;
var filteredItems = context.Items.ToList()
    .Where(x => x.DateTimeColumn.TimeOfDay >= start
        && x.DateTimeColumn.TimeOfDay <= end);
0 голосов
/ 03 апреля 2012

- Вы можете использовать свойство TimeOfDay для дат, чтобы сравнить их.

string timeAsString = "13:00";

from f in TableRows
where f.Date.TimeOfDay > DateTime.Parse("11-12-2012 "+timeAsString).TimeOfDay
select f

EDIT

вот код, который вы можете проверить, который работает для меня:

  DateTime d = DateTime.Parse("12-12-2012 13:00");
  List<DateTime> dates = new List<DateTime>();
  dates.Add(DateTime.Parse("12-12-2012 13:54"));
  dates.Add(DateTime.Parse("12-12-2012 12:55"));
  dates.Add(DateTime.Parse("12-12-2012 11:34"));
  dates.Add(DateTime.Parse("12-12-2012 14:53"));

  var result = (from f in dates where f.TimeOfDay > d.TimeOfDay select f);

РЕДАКТИРОВАТЬ 2

Да, похоже, вам нужно было .ToList (), что, должно быть, вы смогли бы выяснить. У меня не было возможности узнать, какая у тебя коллекция. Не уверен, что кто-либо из нас заслуживает отрицательного ответа за попытку помочь вам, если вы не предоставили огромное количество информации о проблеме

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...