Does Dapper need a type mapper to handle the following scenario.
Let's assume, the database (Postgres) has a column that is in JSONB: Events
which in C# is a List<Event>
with Event
as simple as:
public sealed class Event
{
public string Test { get; set; } = string.Empty;
}
If I add a generic JSON mapper to Dapper like this:
SqlMapper.AddTypeHandler(new JsonMapper<Event>());
with the mapper itself using the following code:
public class JsonMapper<T> : SqlMapper.TypeHandler<T> where T : class, new()
{
public override T Parse(object? value)
{
var config = new T();
if (value is not null)
{
var stringValue = value.ToString() ?? string.Empty;
config = JsonConvert.DeserializeObject<T>(stringValue, NewtonsoftJsonSerializerSettings);
}
return config ?? new();
}
public override void SetValue(IDbDataParameter parameter, T? value)
{
parameter.Value = JsonConvert.SerializeObject(value, NewtonsoftJsonSerializerSettings);
}
private static JsonSerializerSettings NewtonsoftJsonSerializerSettings = new()
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented,
ObjectCreationHandling = ObjectCreationHandling.Replace,
// Don't care about these, not relevant for the question
//Converters = new List<JsonConverter> { new IsoDateTimeConverter(), new IpAddressConverter(), new IpEndpointConverter() }
};
}
do I need to add SqlMapper.AddTypeHandler(new JsonMapper<List<Event>>());
as well or does Dapper get this implicitely somehow?
I have tested this now: You really have to add all type handlers for all types you want to map explicitely. So in my example, you would need SqlMapper.AddTypeHandler(new JsonMapper<Event>());
as well as SqlMapper.AddTypeHandler(new JsonMapper<List<Event>>());
.