Запрос LINQ to SQL не возвращает правильную дату DateTime

Я пытаюсь вытащить последнее поле DateTime из SQLite и возвращает неправильное время.

Вот данные в базе данных:

enter image description here

И вот мой метод для получения последней даты DateTime через LINQ:

    public string getLastSyncTime()
    {
        using (var db = new SQLite.SQLiteConnection(this.DBPath))
        {
            var query = db.Table<SyncAudit>()
                       .OrderByDescending(c => c.SyncTime)
                       .Select(c => c.SyncTime)
                       .FirstOrDefault();

          return query.ToString();
        }
    }

Проблема заключается в том, что он не возвращает ожидаемое время. Я получаю 1/1/0001 12 утра:

enter image description here

Что я делаю неправильно?

РЕДАКТИРОВАТЬ: это используемый поставщик, за запрос: https://components.xamarin.com/view/sqlite-net

Изменить 2: Запрошенный класс SyncAudit:

class SyncAudit
{
    public string Server { get; set; }
    public string Database { get; set; }
    public DateTime SyncTime { get; set; }
    public int Successful { get; set; }
}

Ответы

Ответ 1

Изменить

public DateTime synctime {get; задавать; }

в

public DateTime? synctime {get; задавать; }

Надеюсь, это поможет. То, что происходит, - это тип данных DateTime NOT NULL, и он принудительно устанавливает значение по умолчанию там (01/01/0001), чтобы удостовериться, что будет отображаться непустая дата. Не знаю, может ли это быть проблемой. и проверьте

Ответ 2

Я просмотрел все возможные сценарии, когда этот результат может произойти. Существует только одно логическое объяснение вашей проблемы. Ваш

db.Table<SyncAudit>()

- пустой набор, и когда вы выбираете

db.Table<SyncAudit>()
                   .OrderByDescending(c => c.SyncTime)
                   .Select(c => c.SyncTime)
                   .FirstOrDefault();

он, естественно, вернет вам значение по умолчанию DateTime. Проверьте подключение к базе данных и убедитесь, что она работает в первую очередь.

Ответ 3

Чтобы выяснить, в чем проблема, вернитесь к основам. Измените LINQ в цикл foreach, чтобы перебрать все записи и найти самое большое значение. Теперь пройдите через код (потому что я подозреваю, что не буду делать то, что вы ожидаете), и вы увидите, что происходит не так. Тогда скажите нам, что не так.

Ответ 4

У меня часто возникает эта проблема, используя Select с SQLite. Я не знаю, где проблема на самом деле, но кажется, что ленивая загрузка нарушена, поэтому вы получаете значения по умолчанию, когда приходит время для оценки запроса. Я решаю это, вызывая оценку до Select. Это раздражает, но работает:

Сломанный пример (мой собственный):

        using (var db = new SQLiteConnectionWithLock(base.DatabasePath))
        {
            return db.Table<VideoUploadChunk>()
                .Where(c => c.VideoId == videoId)
                .Select(c => c.ChunkNumber)
                .ToList();
        }

Это должно вернуть список ints, но в итоге он возвращает группу из 0 (по умолчанию).

Исправлен пример:

        using (var db = new SQLiteConnectionWithLock(base.DatabasePath))
        {
            var result = db.Table<VideoUploadChunk>()
                .Where(c => c.VideoId == videoId)
                .ToList();

            return result.Select(c => c.ChunkNumber);
        }

Ваш пример (надеюсь, исправлен):

    using (var db = new SQLite.SQLiteConnection(this.DBPath))
    {
        var query = db.Table<SyncAudit>()
                   .OrderByDescending(c => c.SyncTime)
                   .FirstOrDefault();

        return query.Select(c => c.SyncTime).ToString();
    }

Ответ 5

SQLite не имеют специального типа для даты и времени, вместо этого он использует либо номер, либо текст для хранения таких данных. Конструктор SQLiteConnection имеет параметр storeDateTimeAsTicks, который сообщает вашему провайдеру, как он должен интерпретировать и хранить значения даты и времени. Это верно по умолчанию.

Поэтому, возможно, SyncTime хранится в вашей базе данных как текст, а не номер. Попробуйте настроить соединение, чтобы провайдер мог правильно интерпретировать данные, передав false как storeDateTimeAsTicks:

var db = new SQLite.SQLiteConnection(this.DBPath, storeDateTimeAsTicks: false)