Если вы конвертируете значение даты в двойное число и используете дробную часть 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
.