Подтвердить что ты не робот

Как сравнить DateTime без времени через LINQ?

У меня

var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);

Но он сравнивает, включая временную часть DateTime. Мне это действительно не нужно.

Как сделать это без времени?

Спасибо!

4b9b3361

Ответ 1

Просто используйте свойство 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 этот конкретный фрагмент кода, который вы, возможно, захотите передать дату, но вы будете получать его откуда-то - и ввод часов означает, что вы можете протестировать весь код.

Ответ 2

Свойство 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);

Ответ 3

Попробуйте этот код

var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);

Ответ 4

Бывает, что 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, если он позже.

Ответ 5

Я обнаружил, что в моем случае это единственный способ работы: (в моем приложении я хочу удалить старые записи журнала)

 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 не работает....

Ответ 6

Try

var q = db.Games.Where(t => t.StartDate.Date >= DateTime.Now.Date).OrderBy(d => d.StartDate);

Ответ 7

DateTime dt=DateTime.Now.date;

var q = db.Games.Where(
    t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate
);