Change the default implementation of Dapper's ITypeMap

dapper

Question

I'm looking for a way to change the default implementation of ITypeMap used by Dapper.

The database I am working on uses underscores in all the column names. For example "COLUMN_NAME". I don't want to have my POCO classes use property names with underscores, I'd rather use C# conventions for naming properties on my POCO classes. I also, dont want to have to write long select lists of "COLUMN_NAME AS ColumnName", or even give up the ability to do "SELECT * FROM ..".

I've found that Dapper allows me to write my own ITypeMap, which I have done and it works great! For my case I can write one mapper that will work for any select statement -- it just simply maps column names to property names with the underscores removed. However, because I have my own implementation of ITypeMap I must make a call to SqlMapper.SetTypeMap() at least one time for each POCO type. One of the things I like about Dapper is that there are no setup calls required at all when you use the default mapper. I am desperately trying to hold on to that experience as much as possible, while using the custom ITypeMap.

So instead of the elegant:

connection.Query<Animal>("select..");

I have:

SqlMapper.SetTypeMap(typeof(Animal), new TypeMap<Animal>());
connection.Query<Animal>("select..");

There is even more code when you start keeping track of which types have already been registered with SetTypeMap().

The best solution I have come up with so far is to wrap all the overrides of SqlMapper.Query(). In the wrapped methods I can check and call SetTypeMap() before calling SqlMapper.Query().

Something like this:

public static class DapperWrapper
{
    private static List<Type> _knownTypes = new List<Type>();

    public static IEnumerable<T> Query2<T>(this IDbConnection cnn, string sql, ...);
    {
        Setup<T>();

        return cnn.Query<T>(sql, ...);            
    }

    private static void Setup<T>()
    {
        Type type = typeof(T);

        if (!_knownTypes.Contains(type))
        {
            SqlMapper.SetTypeMap(type, new TypeMap<T>());
            _knownTypes.Add(type);
        }
    }
}

This gets me back to where I want to be:

connection.Query2<Animal>("select..");

Is there a better way of doing this? It seems like DapperExtensions has something like this in the AutoMapper, but it is not clear to me if that works with SqlMapper.Query().

Popular Answer

Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;

https://stackoverflow.com/a/34536829/1315626




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why