类似于这个问题
How can I get Dapper to map .net DateTime to DateTime2
;但我想事后再把它放回去。
目前接受的这个问题的答案是更改Dapper源文件;但是我使用的是NuGet包,所以这对我不起作用。正如对公认答案的第一次评论所指出的,这是不可逆的-
“如果有些是DateTime,有些是DateTime2呢?”
-这就是我的场景:不同的查询需要不同的映射(每个查询只需要一个或另一个)。
我用的是
higher-voted answer
同样的问题。然而,这种方法
也
以下代码是MCVE。如果你运行它,你会看到类型是
总是
显示为“datetime”,并且这些值的精度永远不会超过毫秒(正如您对datetime的期望);尽管尝试更改映射。然后必须注释掉对“PerformDapperQuery()”的第一个调用,并再次运行它:现在您将看到类型是
总是
public static void Main()
{
// I know this is marked as obsolete, and I am open to suggestions for alternatives.
// see https://github.com/StackExchange/Dapper/issues/798
#pragma warning disable 618
var oldValue = SqlMapper.LookupDbType(typeof(DateTime), null, false, out var handler);
#pragma warning restore 618
PerformDapperQuery();
SqlMapper.AddTypeMap(typeof(DateTime), DbType.DateTime2);
PerformDapperQuery();
SqlMapper.AddTypeMap(typeof(DateTime), DbType.DateTime);
PerformDapperQuery();
SqlMapper.AddTypeMap(typeof(DateTime), oldValue);
PerformDapperQuery();
}
private static void PerformDapperQuery()
{
using (var connection = new SqlConnection("server=localhost;Database=master;Integrated Security=SSPI;"))
{
var parameters = new { Param = DateTime.Now };
using (var reader = connection.ExecuteReader(
"SELECT sql_variant_property(@Param, 'BaseType'), CAST(@PARAM AS datetime2(7))", parameters))
{
Assert.That(reader.Read(), Is.True);
string type = reader.GetString(0);
DateTime value = reader.GetDateTime(1);
Console.WriteLine($"Output: {type},{value:o}");
}
}
}
所以问题的第一部分是:我如何可以多次更改Dapper对DateTime的映射?问题的第二部分是我想恢复之前的映射;但是正如您所看到的,
LookupDbType
不相信缓存的达米安解释后编辑
我遇到这个问题的原因是我想添加一些东西来包装特定的Dapper查询,使它们能够使用
DateTime2
而不是
DateTime
,所以我写了这节课:
internal sealed class DapperDateTime2MapperScope : IDisposable
{
private readonly DbType? _predecessor;
private bool _isDisposed;
public DapperDateTime2MapperScope()
{
_predecessor = SqlMapperGetDbType();
SqlMapper.AddTypeMap(typeof(DateTime), DbType.DateTime2);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
if (_predecessor.HasValue)
{
SqlMapper.AddTypeMap(typeof(DateTime), _predecessor.Value);
}
}
_isDisposed = true;
}
}
private DbType SqlMapperGetDbType()
{
#pragma warning disable 618
return SqlMapper.LookupDbType(typeof(DateTime), null, false, out var handler);
#pragma warning restore 618
}
}
然后可以使用它将Dapper查询包装在using块中,使该查询使用DateTime2映射:
using (new DapperDateTime2MapperScope())
{
-- Perform Dapper query here
}
using
还有一个是
使用
;我发现单元测试
相互配合:它们可以单独工作,但当所有测试都运行时,一个或其他测试将失败。原因(多亏达米恩的解释)是Dapper缓存查询。好消息是,我认为这很好——单元测试所遇到的问题是因为它们使用的是同一个查询;但是在我的实际代码库中,如果我将一个特定的查询包装在这个
然后我总是希望该查询使用该映射。所以基本上这只是我的单元测试的问题,而不是类的真正使用。