У меня
var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);
Но он сравнивает, включая временную часть DateTime
. Мне это действительно не нужно.
Как сделать это без времени?
Спасибо!
У меня
var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);
Но он сравнивает, включая временную часть DateTime
. Мне это действительно не нужно.
Как сделать это без времени?
Спасибо!
Просто используйте свойство Date
:
var today = DateTime.Today;
var q = db.Games.Where(t => t.StartDate.Date >= today)
.OrderBy(t => t.StartDate);
Обратите внимание, что я явно оценил DateTime.Today
один раз, чтобы запрос был согласованным - иначе каждый раз, когда выполняется запрос, и даже внутри выполнения, Today
может меняться, поэтому вы получите противоречивые результаты. Например, предположим, что у вас есть данные:
Entry 1: March 8th, 8am
Entry 2: March 10th, 10pm
Entry 3: March 8th, 5am
Entry 4: March 9th, 8pm
Разумеется, либо обе записи 1 и 3 должны быть в результатах, либо ни один из них не должен... но если вы оцениваете DateTime.Today
, и он изменится на 9 марта после того, как он выполнил первые две проверки, вы можете записи 1, 2, 4.
Конечно, использование DateTime.Today
предполагает, что вас интересует дата в локальном часовом поясе. Возможно, это не подходит, и вы должны быть абсолютно уверены, что знаете, что вы имеете в виду. Например, вы можете использовать DateTime.UtcNow.Date
, например. К сожалению, DateTime
- это скользящее зверь...
РЕДАКТИРОВАТЬ: вы также можете вообще избавиться от вызовов статических свойств DateTime
- они усложняют код unit test. В Noda Time у нас есть интерфейс специально для этой цели (IClock
), который мы ожидаем вводиться соответствующим образом. Там существует "системное время" для производства и "заглушка" для тестирования, или вы можете реализовать ее самостоятельно.
Вы можете использовать ту же идею без использования Noda Time, конечно. В unit test этот конкретный фрагмент кода, который вы, возможно, захотите передать дату, но вы будете получать его откуда-то - и ввод часов означает, что вы можете протестировать весь код.
Свойство Date не поддерживается LINQ to Entities - вы получите сообщение об ошибке, если попытаетесь использовать его в поле DateTime в запросе LINQ to Entities. Однако вы можете сократить даты, используя метод DbFunctions.TruncateTime.
В этом случае, конечно, это не имело бы никакого значения, так как обрезанная дата все еще >= сегодня, независимо от того, включен ли вы компонент времени. Если вам нужно было сделать < =, однако, вы хотели бы сделать что-то вроде этого:
var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);
Попробуйте этот код
var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);
Бывает, что LINQ не любит такие свойства, как DateTime.Date
. Он просто не может преобразовать в SQL-запросы. Поэтому я выяснил способ сравнения дат с помощью ответа Джона, но без этого непослушного DateTime.Date
. Что-то вроде этого:
var q = db.Games.Where(t => t.StartDate.CompareTo(DateTime.Today) >= 0).OrderBy(d => d.StartDate);
Таким образом, мы сравниваем полную базу данных DateTime со всеми данными о дате и времени, например 2015-03-04 11: 49: 45.000 или что-то вроде этого, с DateTime, которая представляет фактическую первую миллисекунду этого день, как 2015-03-04 00: 00: 00.0000.
Любое сравнение DateTime с тем, что DateTime.Today
вернет нас безопасно, если эта дата будет позже или то же самое. Если вы не хотите сравнить буквально в тот же день, в этом случае, я думаю, вы должны пойти на ответ Цезаря.
Метод DateTime.CompareTo()
- просто причудливый объектно-ориентированный материал. Он возвращает -1, если параметр раньше, чем DateTime, на который вы ссылались, 0, если он LITERALLY EQUAL (со всеми этими тайм файлами) и 1, если он позже.
Я обнаружил, что в моем случае это единственный способ работы: (в моем приложении я хочу удалить старые записи журнала)
var filterDate = dtRemoveLogs.SelectedDate.Value.Date;
var loadOp = context.Load<ApplicationLog>(context.GetApplicationLogsQuery()
.Where(l => l.DateTime.Year <= filterDate.Year
&& l.DateTime.Month <= filterDate.Month
&& l.DateTime.Day <= filterDate.Day));
Я не понимаю, почему решение Jon не работает....
Try
var q = db.Games.Where(t => t.StartDate.Date >= DateTime.Now.Date).OrderBy(d => d.StartDate);
DateTime dt=DateTime.Now.date;
var q = db.Games.Where(
t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate
);