Saturday, 28 September 2013

Specifying query format in Entity Framework with System.Data.SQLite

Specifying query format in Entity Framework with System.Data.SQLite

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
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.

No comments:

Post a Comment