Mau*_*tro 5 sqlite datetime dapper
我正在使用 Dapper 向 SQLite 插入对象或从 SQLite 获取对象:一个对象具有 DateTime (和 DateTimeOffset)类型的属性,我必须以毫秒精度保留和检索该属性。我找不到正确检索该值的方法,因为 Dapper 失败并显示:
\n\n System.FormatException : String was not recognized as a valid DateTime.\n in System.DateTimeParse.ParseExactMultiple(String\xc2\xa0s,\xc2\xa0String[]\xc2\xa0formats,\xc2\xa0DateTimeFormatInfo\xc2\xa0dtfi,\xc2\xa0DateTimeStyles\xc2\xa0style)\n in System.DateTime.ParseExact(String\xc2\xa0s,\xc2\xa0String[]\xc2\xa0formats,\xc2\xa0IFormatProvider\xc2\xa0provider,\xc2\xa0DateTimeStyles\xc2\xa0style)\n in System.Data.SQLite.SQLiteConvert.ToDateTime(String\xc2\xa0dateText,\xc2\xa0SQLiteDateFormats\xc2\xa0format,\xc2\xa0DateTimeKind\xc2\xa0kind,\xc2\xa0String\xc2\xa0formatString)\n in System.Data.SQLite.SQLite3.GetDateTime(SQLiteStatement\xc2\xa0stmt,\xc2\xa0Int32\xc2\xa0index)\n in System.Data.SQLite.SQLite3.GetValue(SQLiteStatement\xc2\xa0stmt,\xc2\xa0SQLiteConnectionFlags\xc2\xa0flags,\xc2\xa0Int32\xc2\xa0index,\xc2\xa0SQLiteType\xc2\xa0typ)\n in System.Data.SQLite.SQLiteDataReader.GetValue(Int32\xc2\xa0i)\n in System.Data.SQLite.SQLiteDataReader.GetValues(Object[]\xc2\xa0values)\n in Dapper.SqlMapper.<>c__DisplayClass5d.<GetDapperRowDeserializer>b__5c(IDataReader\xc2\xa0r) in SqlMapper.cs: line 2587\n in Dapper.SqlMapper.<QueryImpl>d__11`1.MoveNext() in SqlMapper.cs: line 1572\n in System.Collections.Generic.List`1..ctor(IEnumerable`1\xc2\xa0collection)\n in System.Linq.Enumerable.ToList(IEnumerable`1\xc2\xa0source)\n in Dapper.SqlMapper.Query(IDbConnection\xc2\xa0cnn,\xc2\xa0String\xc2\xa0sql,\xc2\xa0Object\xc2\xa0param,\xc2\xa0IDbTransaction\xc2\xa0transaction,\xc2\xa0Boolean\xc2\xa0buffered,\xc2\xa0Nullable`1\xc2\xa0commandTimeout,\xc2\xa0Nullable`1\xc2\xa0commandType) in SqlMapper.cs: line 1443\n in Dapper.SqlMapper.Query(IDbConnection\xc2\xa0cnn,\xc2\xa0String\xc2\xa0sql,\xc2\xa0Object\xc2\xa0param,\xc2\xa0IDbTransaction\xc2\xa0transaction,\xc2\xa0Boolean\xc2\xa0buffered,\xc2\xa0Nullable`1\xc2\xa0commandTimeout,\xc2\xa0Nullable`1\xc2\xa0commandType) in SqlMapper.cs: line 1382\n
Run Code Online (Sandbox Code Playgroud)\n\n我必须尝试什么?列的类型为 DATETIME。
\n\n我是否必须创建自定义 TypeHandler 并将 DateTime 与格式为“o”的 SQLite 字符串相互转换?
\n\n短小精悍版本1.38
\n我知道它很旧,但我已经找到了解决方案。经过大量挖掘和分析 Dapper 代码后,我想出了这个(请注意,这是 2019 年):
首先,您必须创建日期时间处理程序:
public class DateTimeHandler : SqlMapper.TypeHandler<DateTimeOffset>
{
private readonly TimeZoneInfo databaseTimeZone = TimeZoneInfo.Local;
public static readonly DateTimeHandler Default = new DateTimeHandler();
public DateTimeHandler()
{
}
public override DateTimeOffset Parse(object value)
{
DateTime storedDateTime;
if (value == null)
storedDateTime = DateTime.MinValue;
else
storedDateTime = (DateTime)value;
if (storedDateTime.ToUniversalTime() <= DateTimeOffset.MinValue.UtcDateTime)
return DateTimeOffset.MinValue;
else
return new DateTimeOffset(storedDateTime, databaseTimeZone.BaseUtcOffset);
}
public override void SetValue(IDbDataParameter parameter, DateTimeOffset value)
{
DateTime paramVal = value.ToOffset(this.databaseTimeZone.BaseUtcOffset).DateTime;
parameter.Value = paramVal;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,请注意 Dapper 将 .Net 的类型 DateTimeOffset 转换为 dbType - DateTimeOffset。您需要删除此映射并添加您自己的映射,如下所示:
SqlMapper.RemoveTypeMap(typeof(DateTimeOffset));
SqlMapper.AddTypeHandler(DateTimeHandler.Default);
Run Code Online (Sandbox Code Playgroud)
就这样。现在,每次 Dapper 在模型中看到 DateTimeOffset 属性时,它都会运行 DateTimeHandler 来管理它。
我发现无法使用基类型的自定义 TypeHandler,因为在查找 TypeHandler 之前选择了默认 typeMap。
我已经打开了一个问题dapper-dot-net,但同时我已经解决了通过反射将默认 typeMap 替换为新的 typeMap(如前一个减去四个键 DateTime、DateTime?、DateTimeOffset、DateTimeOffset?)的问题。
归档时间: |
|
查看次数: |
5908 次 |
最近记录: |