Dapper icon indicating copy to clipboard operation
Dapper copied to clipboard

TypeHandler.Parse not call for null values

Open Duffscs opened this issue 2 years ago • 0 comments

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

Duffscs avatar Jul 17 '23 19:07 Duffscs