当前位置:网站首页>How to make dapper support dateonly type
How to make dapper support dateonly type
2022-06-29 13:34:00 【Dotnet cross platform】
Preface
stay Last article in , We let EF Core 6 Support DateOnly type .
that ,Dapper Do you support DateOnly Type? ?
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public DateOnly Birthday { get; set; }
}
using (var connection = new SqlConnection(connectionString))
{
var users = connection.Query<User>("select * from users");
}Not good either. :

Because the exception prompt has no guiding significance , So we want to start with the source code .
In depth exploration
call Stack
Through the call stack , Locate the location where the exception occurred at SqlMapper.cs The first 1113 That's ok :

The first 1113 The specific code of the line is as follows :

among func The source of this is tuple.Func, and tuple Is assigned in the following way :
tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); notice Deserializer The word , Immediately attracted our attention : serialize
GetDeserializer Method
Come and see GetDeserializer Method implementation :
private static Func<IDataReader, object> GetDeserializer(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing)
{
// dynamic is passed in as Object ... by c# design
if (type == typeof(object) || type == typeof(DapperRow))
{
return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing);
}
Type underlyingType = null;
if (!(typeMap.ContainsKey(type) || type.IsEnum || type.IsArray || type.FullName == LinqBinary
|| (type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum)))
{
if (typeHandlers.TryGetValue(type, out ITypeHandler handler))
{
return GetHandlerDeserializer(handler, type, startBound);
}
return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing);
}
return GetStructDeserializer(type, underlyingType ?? type, startBound);
} Method from typeHandlers In order to get ITypeHandler Interface implementation .
and ITypeHandler The interface is defined as follows :
/// <summary>
/// Implement this interface to perform custom type-based parameter handling and value parsing
/// </summary>
public interface ITypeHandler
{
/// <summary>
/// Assign the value of a parameter before a command executes
/// </summary>
/// <param name="parameter">The parameter to configure</param>
/// <param name="value">Parameter value</param>
void SetValue(IDbDataParameter parameter, object value);
/// <summary>
/// Parse a database value back to a typed value
/// </summary>
/// <param name="value">The value from the database</param>
/// <param name="destinationType">The type to parse to</param>
/// <returns>The typed value</returns>
object Parse(Type destinationType, object value);
}Implement this interface to perform custom type based parameter processing and value parsing
Isn't that exactly what we want ?
AddTypeHandler Method
And how to Dapper Pass in ITypeHandler To achieve? ?
We finally found AddTypeHandler Method :
/// <summary>
/// Configure the specified type to be processed by a custom handler.
/// </summary>
/// <param name="type">The type to handle.</param>
/// <param name="handler">The handler to process the <paramref name="type"/>.</param>
public static void AddTypeHandler(Type type, ITypeHandler handler) => AddTypeHandlerImpl(type, handler, true);Configure the specified type to be handled by the custom handler
Realization
First , establish ITypeHandler Realization :
public class DateOnlyTypeHandler : TypeHandler<DateOnly>
{
public override DateOnly Parse(object value)
{
return DateOnly.FromDateTime((DateTime)value);
}
public override void SetValue(IDbDataParameter parameter, DateOnly value)
{
parameter.Value = value.ToDateTime(TimeOnly.MinValue);
}
}then , Add a custom handler at startup :
SqlMapper.AddTypeHandler<DateOnly>(new DateOnlyTypeHandler());Now? , The program can run normally .
Conclusion
today , We introduced the use of customization ITypeHandler To tell Dapper How to handle data types that are not supported by default .
Add microsignals 【MyIO666】, Invite you to join the technical exchange group
边栏推荐
- Uncover the secret! Pay attention to those machines under the membership system!
- netdata邮件告警配置
- 神经网络各个部分的作用 & 彻底理解神经网络
- Leetcode 179 Maximum number (2022.06.28)
- Yolo series combs (IX) first taste of newly baked yolov6
- RT thread memory management
- Exploring the way of automated testing - Preparation
- leetcode 903. DI 序列的有效排列
- Record the process of a solid-state update and system migration debug
- Write a shell script to find the "reverse order" of a number“
猜你喜欢

Cvpr2022 𞓜 future transformer with long-term action expectation

Ordinary users use vscode to log in to SSH and edit the root file

win32版俄罗斯方块(学习MFC必不可少)

华为机器学习服务语音识别功能,让应用绘“声”绘色

Uncover the secret! Pay attention to those machines under the membership system!

Imile uses Zadig's multi cloud environment to deploy thousands of times a week to continuously deliver global business across clouds and regions

DeeCamp2022正式开营!李开复、张亚勤亲授大师课 | 创新事

Yolo series combs (IX) first taste of newly baked yolov6

SCHIEDERWERK電源維修SMPS12/50 PFC3800解析

STK_ Gltf model
随机推荐
如何统计项目代码(比如微信小程序等等)
安装terraform-ovirt插件为ovirt提供自动化管理
C语言内存函数
hutool工具类的学习(持续更新)
CVPR2022 | 通过目标感知Transformer进行知识蒸馏
PG基础篇--逻辑结构管理(1)
weserver发布地图服务
bind原理及模拟实现
Clickhouse database uses JDBC to store milliseconds and nanoseconds
【系统设计】邻近服务
MySQL tuning
AOSP ~ logcat persistence
How to count project codes (e.g. wechat applets)
Code tidiness learning notes
iMile 利用 Zadig 多云环境周部署千次,跨云跨地域持续交付全球业务
Exploring the way of automated testing - Preparation
C语言模拟实现所有字符函数
Can I open an account online? Is it safe
Netdata data data persistence configuration
SCHIEDERWERK電源維修SMPS12/50 PFC3800解析