Как использовать DateTime в предложении where в Sqlite.Net

Я пишу мобильное приложение, которое использует Sqlite.Net. Я пытаюсь отфильтровать Table с помощью свойства DateTime и LINQ to SQL.

У меня есть следующий фрагмент кода:

 var validDates = Database.Connection.Table<Dates>()
        .Where(x => x.StartDate <= DateTime.Today && x.EndDate >= DateTime.Today)
       .ToList();

Но это выдает Ссылка на объект, не установленную для экземпляра объекта. И трассировка стека, кажется, предполагает, что ошибка находится в библиотеке Sqlite.Net, что заставляет меня поверить, что я неправильно использую DateTimes.

Предупреждение: необработанное исключение: System.Reflection.TargetInvocationException: Исключение было создано целью вызова. ---> System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта. 09-28 13:01:24.293 W/Xamarin.Insights(31238): в SQLite.Net.TableQuery1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1[T] queryArgs) [0x00613] в ‹8f2bb39aeff94a30a8628064be9c7efe>:0 09-28 13:01:24.293 W/Xamarin.Insights (31238): в SQLite.Net.TableQuery1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1[T] queryArgs) [0x0064b] в ‹8f2bb39aeff94a30a8628064be9c7efe>:0 09-28 13:01:24.293 W/Xamarin.Insights(31238): в SQLite.Net.TableQuery1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1[T] Queryargs) [0x00027] в ‹8f2bb39aeff94a30a8628064be9c7efe>: 0 09-28 13: 01: 24.293 w/xamarin.insights (31238): at sqlite.net.tablequery1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1 [t] Queryargs) [0x0002.f.f0002.f.fcompfile. 28 13:01:24.293 W/Xamarin.Insights(31238): в SQLite.Net.TableQuery1[T].GenerateCommand (System.String selectionList) [0x0006d] in <8f2bb39aeff94a30a8628064be9c7efe>:0 09-28 13:01:24.293 W/Xamarin.Insights(31238): at SQLite.Net.TableQuery1[T].GetEnumerator () [0x00008] в ‹8f2bb39aeff94a30a8628064be9c7efe>:0 09-28 13:01:24.293 W/Xamarin.Insight (31238): в коллекции System.Collections.Generic.List1[T]..ctor (System.Collections.Generic.IEnumerable1[T]) [0x00073] в /Users/builder/data/lanes/3819/c1d1c79c/source/mono/mcs/class/referencesource/mscorlib/system/collections/ универсальный/список.cs:98 09-28 13: 01:24.293 W/Xamarin.Insights(31238): в System.Linq.Enumerable.ToList[TSource] (источник System.Collections.Generic.IEnumerable`1[T]) [0x00011] в /Users/builder/data/lanes /3819/c1d1c79c/source/mono/mcs/class/referencesource/System.Core/System/Linq/Enumerable.cs:861

Выполнение этого как SQL statemnet работает следующим образом:

 var query = string.Format("Select * from [Dates.Dates] where StartDate<=date('{0:yyyy-MM-dd}') and EndDate>=date('{1:yyyy-MM-dd}')", DateTime.Today, DateTime.Today);

Но есть ли способ выполнить запрос DateTime с помощью LINQ to SQL?

Вот источник и метод, в котором возникает ошибка

Дополнительная информация

Моя настройка StoreDateTimeAsTicks установлена ​​на True

И Мои определения для StartDate и EndDate оба DateTimes

Мой класс Dates выглядит так:

[Table("Dates.Dates")]
public class Dates : BaseModel
{
    public Dates()
    {
        //Don't fire notifications by default, since
        //they make editing the properties difficult.
        this.NotifyIfPropertiesChange = false;
    }

    [PrimaryKey]
    [NotNull]
    [AutoIncrement, Column("Id")]
    public int Id 
    { 
        get { return Id_private; }
        set { SetProperty(Id_private, value, (val) => { Id_private = val; }, Id_PropertyName); }
    }
    public static string Id_PropertyName = "Id";
    private int Id_private;

    [NotNull]
    [Column("Name")]
    public string Name 
    { 
        get { return Name_private; }
        set { SetProperty(Name_private, value, (val) => { Name_private = val; }, Name_PropertyName); }
    }
    public static string Name_PropertyName = "Name";
    private string Name_private;

    [NotNull]
    [Column("StartDate")]

    // The actual column definition, as seen in SQLite
    public string StartDate_raw { get; set; }

    public static string StartDate_PropertyName = "StartDate";

    // A helper definition that will not be saved to SQLite directly.
    // This property reads and writes to the _raw property.
    [Ignore]
    public DateTime StartDate { 
        // Watch out for time zones, as they are not encoded into
        // the database. Here, I make no assumptions about time
        // zones.
        get { return StartDate_raw != null ? DateTime.Parse(StartDate_raw) : StartDate = DateTime.Now; }
        set { SetProperty(StartDate_raw, StartDate_ConvertToString(value), (val) => { StartDate_raw = val; }, StartDate_PropertyName); }
    }

    // This static method is helpful when you need to query
    // on the raw value.
    public static string StartDate_ConvertToString(DateTime date)
    {    
        return date.ToString("yyyy-MM-dd");     
    }           

    [NotNull]
    [Column("EndDate")]

    // The actual column definition, as seen in SQLite
    public string EndDate_raw { get; set; }

    public static string EndDate_PropertyName = "EndDate";

    // A helper definition that will not be saved to SQLite directly.
    // This property reads and writes to the _raw property.
    [Ignore]
    public DateTime EndDate { 
        // Watch out for time zones, as they are not encoded into
        // the database. Here, I make no assumptions about time
        // zones.
        get { return EndDate_raw != null ? DateTime.Parse(EndDate_raw) : EndDate = DateTime.Now; }
        set { SetProperty(EndDate_raw, EndDate_ConvertToString(value), (val) => { EndDate_raw = val; }, EndDate_PropertyName); }
    }

    // This static method is helpful when you need to query
    // on the raw value.
    public static string EndDate_ConvertToString(DateTime date)
    {    
        return date.ToString("yyyy-MM-dd");     
    }
}

person user1    schedule 28.09.2016    source источник
comment
@mybirthname Нет, это не дубликат. Там совсем другой контекст.   -  person Shaharyar    schedule 28.09.2016
comment
Вы пытались установить DateTime.Today в переменную? Некоторые поставщики LINQ не поддерживают функции (или поведение, подобное функции) в инструкциях LINQ.   -  person ADIMO    schedule 28.09.2016
comment
@A.DIMO Только что попробовал, и, к сожалению, все еще ошибается   -  person user1    schedule 28.09.2016
comment
@HenkHolterman Я обновил вопрос с соответствующей информацией   -  person user1    schedule 28.09.2016
comment
Это имеет большое значение. Ваши фактические столбцы Db - это String, а не DateTime.   -  person Henk Holterman    schedule 28.09.2016
comment
@HenkHolterman Sqlite.Net представляет DateTime как string, нет такой вещи, как DateTime в Sqlite.Net, см. здесь   -  person user1    schedule 28.09.2016
comment
Нет, но sqlite.net может хранить это как тики. И механизм запросов знает, как с этим справиться (в сочетании с DateTime)   -  person Henk Holterman    schedule 28.09.2016


Ответы (2)


Попробуй это:

string dateToday = DateTime.Today;
var validDates = Database.Connection.Table<Dates>().Where(x => x.StartDate <= dateToday && x.EndDate >= dateToday).ToList();
person Shaharyar    schedule 28.09.2016
comment
вы пробовали это? Это все еще ошибка на моем конце - person user1; 28.09.2016
comment
Нет, я этого не сделал. Ваш простой запрос работает Database.Connection.Table<Dates>() без этого условия даты и времени? - person Shaharyar; 28.09.2016
comment
да, он возвращает всю таблицу. Я не могу не чувствовать, что это может быть связано с тем фактом, что Sqlite хранит DateTimes в виде строк, а не фактическое DateTimes - person user1; 28.09.2016
comment
Какой sql-запрос генерирует этот linq-запрос? - person Shaharyar; 28.09.2016
comment
Выберите * из [Даты]. но тот, что в этом ответе, не генерирует sql, он все равно просто падает, прежде чем достигнет этого - person user1; 28.09.2016

Итак, проблема заключалась в том, что мои свойства StartDate и EndDate в моем классе НЕ ЯВЛЯЮТСЯ столбцами. Это всего лишь оболочки для настоящих свойств StartDate_Raw и EndDate_Raw. Которые strings.

Поскольку столбцы Raw были строками, это означало, что я также не могу фильтровать базу данных с помощью LINQ to SQL, используя строковые даты, поэтому я был в тупике.

Ограничение, заключающееся в том, что мои даты хранились в виде строк, является ограничением некоторого стороннего программного обеспечения, которое я использую, которое называется Zumero. Если бы я не использовал это, я бы просто изменил схему таблицы на int.

Итак, в итоге я изменил все свои столбцы DateTime в моей базе данных SQL на Ticks и сохранил как Ints, это означало, что я мог изменить свое свойство string DateTime на int и использовать LINQ to SQL следующим образом:

var validDates = Database.Connection.Table<Dates>()
        .Where(x => x.StartDate_Raw <= DateTime.Today && x.EndDate_Raw >= DateTime.Today)
       .ToList();
person user1    schedule 31.10.2016