Pergunta

I have an Entity Framwework 4.0 Model running against an SQLite database to which I connect via System.Data.SQLite. I have one field in the database which is typed "Date", and formatted as yyyy-MM-dd. (As we know, SQLite has no internal Date or DateTime type).

The Entity Framework wizard happily translated that Date type to DateTime. When running queries against this date field, I was surprised to find out no results came.

Suppose a table "MyTable":

Create Table MyTable
(
    Id Integer Not Null Primary Key,
    ADate Date Not Null
);

With System.Data.SQLite and LINQ:

var date = new DateTime(2013, 1, 1);
context.MyTables.AddObject(new MyTable { Id = 0, ADate = date });
context.SaveChanges();
context.MyTables.Where(r => r.ADate == date).Count; // -> returns 0

Looking further with ToTraceQuery, I found out that the query became:

SELECT
[Extent1].[Id] AS [Id], 
[Extent1].[ADate] AS [ADate]
FROM [TestDate] AS [Extent1]
WHERE [Extent1].[ADate] = @p__linq__0

With testing, I discovered that the mapped variable p__linq__0 was transformed to a fixed format of yyyy-MM-dd hh:mm:ss, so that asking for DateTime(2013,1,1) meant the query was looking for '2013-01-01 00:00:00' when all that was to be found was '2013-01-01'.

If the folks who make 'System.Data.SQLite' had been nice about this, they'd have used the built in SQLite functions and done the comparison like:

WHERE datetime([Extent1].[ADate]) = datetime(@p__linq__0)

or even

WHERE date([Extent1].[ADate]) = date(@p__linq__0)

for just the date type. And indeed in System.Data.SQLite's SqlGenerator.cs, we find this formatting for all DateTime types:

((System.DateTime)e.Value).ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture), false /* IsUnicode */)

All this to say, is there a way to specify the format for this where clause in this context?

Notes: SQLite is what I'm stuck with, and the recorded format of 'yyyy-MM-dd' cannot be changed as other software relies on it.

Foi útil?

Solução

One alternative to ExecuteStoreQuery is to pass other where clauses first (if any) then force the query to run (for example with ToList()), and finally to apply standard LINQ filters on the special format Date field afterwards.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top