Запрос 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)