Dapper
Dapper copied to clipboard
TypeHandler.Parse not call for null values
I want to wrap my value inside an Option, the code is really simple. But when value is null OptionTypeHandler.Parse() isn't called. So my Option instead of being None is null.
Consider adding a ParseNull() to handle null value
Here is an illustration :
public static class DapperConfig {
public static void Run() {
...
AddTypeHandler(new OptionTypeHandler<string>());
AddTypeHandler(new OptionTypeHandler<string?>());
}
}
public class OptionTypeHandler<T> : TypeHandler<Option<T>>{
public override void SetValue(IDbDataParameter parameter, Option<T> value)
=> parameter.Value = value.IsSome() ? value.Unwrap() : DBNull.Value;
public override Option<T> Parse(object value)
=> value == null || value == DBNull.Value ? Option.None<T>() : Option.Some((T)value);
}
public struct User {
public int Id { get; set; }
public string Name { get; set; }
public Option<string> Mail { get; set; }
}
public class UserRepository {
private readonly IDbConnection connection;
public UserRepository(IDbConnection connection) {
this.connection = connection;
}
public Option<User> GetUserById(int userId) {
string query = "SELECT user_id as Id, user_name as Name, user_mail as Mail FROM Users WHERE user_id = @UserId";
var parameters = new { UserId = userId };
return connection.QueryFirstOrDefault<User>(query, parameters); // implicit cast to Some or None don't pay attention
}
}
public static void Main() {
DapperConfig.Run();
using IDbConnection connection = new SQLiteConnection(Const.CONNECTION_STRING);
connection.Open();
UserRepository userRepository = new(connection);
Option<User> userOpt1 = userRepository.GetUserById(1);
if (userOpt1.IsSome && userOpt1.Unwrap() is User user)
Debug.WriteLine($"User found - Id: {user.Id}, Name: {user.Name}, Mail: {(user.Mail.IsSome ? user.Mail.Unwrap() : "")}");
else
Debug.WriteLine("User not found");
}
// option code :
// https://gist.github.com/bojanrajkovic/b1ff4d52fccffcf7e6e98aa041b52ee7