如何通过SQLProvider类型提供程序与SQLite一起使用DateTime?
SQLite实际上没有日期和时间数据类型(请参阅Data types)并将日期存储为文本。我可以传递一个日期字符串并查询它,然后返回一个字符串。所以这是有效的,其中table3中的Date1存储为字符串:
query {
for r in table3 do
select (r.Date1)
} |> Seq.toList
val it : string list =
["2016/06/09 0:00:00"; "2016/06/05 0:00:00"; "2016/06/04 0:00:00";
"2016/06/12 0:00:00"; "2016/06/10 0:00:00"; "2016/06/06 0:00:00";
也可以将Date1存储为DateTime,而在另一个表中我也可以存储它。即使SQLite不理解DateTime,我也可以使用DateTime数据类型创建一个列,并且可以在其中存储DateTime值。例如,我可以在C#(或LinqPad)中提取此值。但是当我尝试通过类型提供程序(允许我存储DateTime值的相同类型提供程序)访问它时,它会出现以下错误:
System.FormatException: String was not recognized as a valid DateTime.
> at System.DateTimeParse.ParseExactMultiple(String s, String[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style)
at System.Data.SQLite.SQLiteConvert.ToDateTime(String dateText, SQLiteDateFormats format, DateTimeKind kind, String formatString)
at System.Data.SQLite.SQLite3.GetDateTime(SQLiteStatement stmt, Int32 index)
at System.Data.SQLite.SQLite3.GetValue(SQLiteStatement stmt, SQLiteConnectionFlags flags, Int32 index, SQLiteType typ)
at System.Data.SQLite.SQLiteDataReader.GetValue(Int32 i)
at <StartupCode$FSharp-Data-SqlProvider>.$SqlRuntime.DataContext.FSharp-Data-Sql-Common-ISqlDataContext-ReadEntities@153.GenerateNext(IEnumerable`1& next)
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.MoveNextImpl()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable`1 source)
at FSharp.Data.Sql.Runtime.QueryImplementation.executeQuery(ISqlDataContext dc, ISqlProvider provider, SqlExp sqlExp, List`1 ti)
at FSharp.Data.Sql.Runtime.QueryImplementation.SqlQueryable`1.System-Collections-Generic-IEnumerable`1-GetEnumerator()
at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable`1 source)
at <StartupCode$FSI_0075>.$FSI_0075.main@()
table3中的working(类型提供程序)查询与table2中的错误查询之间的区别是列的数据类型:
LinqPad在Table2中正确地将其视为DateTime,此查询在那里工作:
var dt2 = new System.DateTime(2016,8,30,0,0,0,DateTimeKind.Local);
Table2
.Where(r => r.Date1 == dt2).Dump();
答案 0 :(得分:1)
DateTime类型与SQLProvider 1.0.31和SQLite 1.0.102的以下版本一起正常工作:
#if INTERACTIVE
#I @"..\packages\SQLProvider.1.0.31\lib"
#r "FSharp.Data.SqlProvider.dll"
#I @"..\packages\System.Data.SQLite.Core.1.0.102.0\lib\net46"
#r "System.Data.SQLite.dll"
#I @"..\packages\System.Data.SQLite.Linq.1.0.102.0\lib\net46"
#r "System.Data.SQLite.Linq.dll"
#endif
open System
open FSharp.Data.Sql
//open System.Data.SQLite
//open System.Data.SQLite.Linq
[<Literal>]
let connectionString = "Data Source="+ @"C:\tmp\databaseFile.db3"
[<Literal>]
let resolutionPath = __SOURCE_DIRECTORY__ + @"..\..\packages\System.Data.SQLite.Core.1.0.102.0\lib\net46"
type sql = SqlDataProvider<
Common.DatabaseProviderTypes.SQLITE,
connectionString,
ResolutionPath = resolutionPath,
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL>
let ctx = sql.GetDataContext()
let table2 = ctx.Main.Table2 //DateTime
let table3 = ctx.Main.Table3 //Text