質問

I ran into something strange today by query-ing an 32 bits SQLite embedded database using ServiceStack ORMLite (Testing on Windows 2012 Server, .NET Framework 4.0).

Consider the following test queries:

var dateMinimum = DateTime.Now.Subtract(_doNotProcessQueueItemWhenOlderThanHours);
using (var db = DbConnectionFactory.OpenDbConnection())
{
    var queueItemsTest1 = db.Select<ProcessQueue>(pc => (pc.Status == ProcessingStatus.Failed.ToString()) && (pc.DateCreated > dateMinimum)).ToList();
    var queueItemsTest2 = db.Select<ProcessQueue>(pc => (pc.Status == ProcessingStatus.Failed.ToString())).ToList();
    var queueItemsTest3 = db.Select<ProcessQueue>(pc => (pc.DateCreated > dateMinimum)).ToList();


    var queueItemsUnparsed = db.Select<ProcessQueue>().ToList();
    var queueItems = new List<ProcessQueue>();
    foreach (var queueItemUnparsed in queueItemsUnparsed)
    {
        if ((queueItemUnparsed.Status == ProcessingStatus.Failed.ToString()) && (queueItemUnparsed.DateCreated > dateMinimum))
        {
            queueItems.Add(queueItemUnparsed);
        }
    }
}

public class ProcessQueue
{
    [AutoIncrement]
    public int Id { get; set; }
    public DateTime DateCreated { get; set; }
    public string Status { get; set; }
}

What is strange that:

  • queueItemsTest1 returns nothing
  • queueItemsTest2 returns all correct rows
  • queueItemsTest3 returns nothing
  • The foreach construction returns the correct rows.

Is there some way to log what is going on inside the database?

I think it is SQLite related because I have another queue which talks to SQL server and this works. I am using SQLite because this queue must be embedded and could not find a way to make ORMLite work with SQL Compact.

役に立ちましたか?

解決

Is there some way to log what is going on inside the database?

The simplest way is to use Console.WriteLine(db.GetLastSql());

So in your case:

var queueItemsTest1 = db.Select<ProcessQueue>(pc => (pc.Status == ProcessingStatus.Failed.ToString()) && (pc.DateCreated > dateMinimum)).ToList();
Console.WriteLine(db.GetLastSql());

var queueItemsTest2 = db.Select<ProcessQueue>(pc => (pc.Status == ProcessingStatus.Failed.ToString())).ToList();
Console.WriteLine(db.GetLastSql());

var queueItemsTest3 = db.Select<ProcessQueue>(pc => (pc.DateCreated > dateMinimum)).ToList();
Console.WriteLine(db.GetLastSql());

Then you should be able to use the SQL output to determine what query it is building. If I were to hazard a guess I would say it's to do with the Date handling.


You can't use the DateTime object because SQLite does not support a corresponding format.

From the SQLite documentation:

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

  • TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
  • REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
  • INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.

Using DateTime.Ticks should provide an appropriate long.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top