Почему я не могу запросить поле DATETIME с помощью EF6 и SQlite?

У меня есть приложение WPF, использующее EF6 и Sqlite. Я пытаюсь запустить относительно простой запрос, который сравнивает даты. Я прочитал тысячу статей о sqlite и датах, и я все еще застрял.

Я не думаю, что это имеет какое-либо отношение к временной части сравнения (т.е. попытка сравнить только дату). Я понимаю, что я мог бы использовать начальную и конечную дату и время для захвата записей, которые находятся между ними. Я думаю, что это связано с фактическим sql, который генерируется orm.

Я думаю, что проблема связана с SQL, сгенерированным EF6. В моей таблице SQlite есть поле DATETIME, которое представляет собой строковое значение в следующем формате: «2019-03-23 ​​00:00:00.000».

Когда я запускаю запрос как часть приложения в режиме отладки VS, запрос не возвращает результатов, и я вижу из зарегистрированного sql параметр в предложении where: p__linq__0: '23/03/2019 00:00:00'

Когда я запускаю тот же самый запрос с помощью Linqpad (нацеленный на ту же базу данных с той же ссылкой на dll), запрос действительно возвращает записи, как я и ожидал, и я заметил, что sql, сгенерированный linqpad, использует этот формат для параметра @p__linq__0 DateTime2 = '2019 -03-23 ​​00:00:00.0000000'

В приложении я ссылаюсь на System.Data.SQLite (v 1.0.110.0) — я не уверен, что использует linqpad.

Я не знаю, как повлиять на сгенерированный SQL в приложении, но linqpad предполагает, что должна быть возможность сгенерировать совместимый sql.

В случае, если это поможет или я лаю не по тому дереву, вот мой запрос linq. Сравнение проводится с параметром «сегодня», который создает другие параметры sql, как указано выше.

public IEnumerable<Menu> GetTodaysMenus()
{
    DateTime today = DateTime.Now.Date;

    var menus = _context.Menus
          .Select(x => new
          {
             x,
             x.SalesBusinessType,
             Date = x.MenuDays.Select(y => y.CalendarDate)
          })
         .Where(x => x.x.DeletedAt == null &&
                     x.x.Published == true &&
                     x.Date.Contains(today))
         .AsEnumerable()
         .Select(x => x.x);

  return menus;
}

Я могу воспроизвести сценарий и изменить конфигурацию базы данных, но не знаю, что делать. Я хочу иметь возможность использовать сравнение дат в своем приложении, как я, кажется, могу сделать при использовании linqpad.

ОБНОВИТЬ:

Этот обновленный запрос получает запись, которую я ожидал. Я до сих пор не уверен, почему и что было "не так" с оригиналом

public IEnumerable<Menu> GetTodaysMenus()
        {
            string today = DateTime.Now.Date.ToString("yyyy-MM-dd HH:mm:ss.fff");

            var menus = _context.Menus
                .Select(x => new
                {
                    x,
                    x.SalesBusinessType,
                    x.MenuDays,
                    Date = x.MenuDays.Select(y => y.CalendarDate.ToString())
                })
                .Where(x => x.x.DeletedAt == null &&
                            x.x.Published == true &&
                            x.Date.Contains(today))
                .AsEnumerable()
                .Select(x => x.x);

            return menus;
        }

ОБНОВЛЕНИЕ 2:

Прямые сравнения работают, например, так (DateTime == сегодня) или в этом примере коллекция DateTime содержит (сегодня), однако диапазоны (т.е. datetime >= сегодня) не работают.

Каков тип данных CalendarDate? Вы говорите, что это поле DateTime, но затем вы говорите, что это строка. БД не хранят даты и время в виде строк, но позволяют запрашивать форматированную строку.

juharr 23.03.2019 23:22

Также вам не нужен этот промежуточный элемент Select, который вы можете использовать x.MenuDays.Select(y => y.CalendarDat).Contains(today) в предложении Where.

juharr 23.03.2019 23:24

Как SQLite хранит дату на диске — это деталь реализации. Стандартный NET SQLite довольно хорошо возвращает даты и другие типы данных NET.

Ňɏssa Pøngjǣrdenlarp 23.03.2019 23:30

@mjwills В этом случае OP может захотеть попробовать запрос с датой, отформатированной как строка.

juharr 23.03.2019 23:30

@mjwills - я не получаю сообщения об ошибке, скорее записи не возвращаются. Я не могу использовать строку на сегодня в запросе, так как объект имеет поле как C# DateTime. Я не знаю, что такое StartsWith, поскольку поле Date в анонимном представляет собой набор DateTime. Где нацелен на дату, которая указана анонимно, поэтому я думаю, что она должна идти после выбора.

Jon 23.03.2019 23:35

@juharr - Тип данных CalendarDate - DateTime в С#, но я понял, что Sqlite хранит дату и время в виде строки, реальной или целочисленной. БД создается из кода с использованием этого пакета nuget, который я нашел SQLite.CodeFirst.

Jon 23.03.2019 23:39

Я подумал, что что-то понял, когда увидел разницу в сгенерированных параметрах sql между зарегистрированным выводом sql в приложении и sql, сгенерированным при использовании linqpad...

Jon 23.03.2019 23:44

@MakeStackOverflowGoodAgain - я надеялся, что провайдер вернет достойный объект DateTime. Я попробовал версию своего кода, в которой я возвращаю все записи в память (эта конкретная таблица небольшая). последующий запрос linq работает, и я могу получить запись. Однако я не работаю, когда запрос сразу отправляется в базу данных. По понятным причинам я не хочу всегда вытаскивать все записи в памяти.

Jon 24.03.2019 12:26

Что, если вы попробуете что-то вроде x.MenuDays.Select(y => y.CalendarDate.ToString()).Contains(todayAsString). Это должно либо привести к некоторому типу SQL, который позволит вам сравнить столбец с отформатированной строкой даты, которая должна совпадать, либо EF выдаст ошибку.

juharr 24.03.2019 12:43
my table has a DATETIME field which is a string value in the following format: "2019-03-23 00:00:00.000" Строка не является датой, а даты не имеют формата. Если вы определяете столбец как строку, поставщик БД не сможет вам помочь (см. ссылку). Также может быть что-то еще неправильное, но сохранение дат в виде строк создает проблемы с преобразованием, а также проблемы с форматом
Ňɏssa Pøngjǣrdenlarp 24.03.2019 15:19

@MakeStackOverflowGoodAgain - я только что читал этот связь, в котором описывались три типа механизмов хранения, которые использует Sqlite, но, как вы сказали, мне все равно. Я просто упомянул об этом, если это имеет отношение к моей проблеме. Объектом в приложении является C# DateTime, и я хочу иметь дело только с DateTimes, но когда sql отправляется в базу данных напрямую, что-то вызывает несоответствие. Я просто не уверен, что.

Jon 24.03.2019 15:32

@juharr - Итак, ваше предложение сработало. Он сгенерировал sql с форматом параметра a, который соответствовал записи... Все еще не уверен, почему и как преобразуются строки vs DateTimes... Тем не менее - спасибо.

Jon 24.03.2019 16:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
732
0

Другие вопросы по теме