我正在寻找一种方法来改变Dapper使用的ITypeMap的默认实现。
我正在处理的数据库在所有列名中使用下划线。例如“COLUMN_NAME”。我不希望我的POCO类使用带下划线的属性名称,我宁愿使用C#约定来命名我的POCO类的属性。我也不想写“COLUMN_NAME AS ColumnName”的长选择列表,甚至放弃“SELECT * FROM ..”的能力。
我发现Dapper允许我编写自己的ITypeMap,我已经完成了它并且效果很好!对于我的情况,我可以编写一个适用于任何select语句的映射器 - 它只是简单地将列名称映射到删除了下划线的属性名称。但是,因为我有自己的ITypeMap实现,所以我必须至少对每个POCO类型调用一次SqlMapper.SetTypeMap()。我喜欢Dapper的一个原因是当你使用默认的映射器时根本不需要设置调用。在使用自定义ITypeMap时,我正在拼命尝试尽可能地保持这种体验。
而不是优雅:
connection.Query<Animal>("select..");
我有:
SqlMapper.SetTypeMap(typeof(Animal), new TypeMap<Animal>());
connection.Query<Animal>("select..");
当您开始跟踪已经使用SetTypeMap()注册的类型时,还有更多代码。
到目前为止,我提出的最佳解决方案是包装SqlMapper.Query()的所有覆盖。在包装的方法中,我可以在调用SqlMapper.Query()之前检查并调用SetTypeMap()。
像这样的东西:
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);
}
}
}
这让我回到了我想成为的地方:
connection.Query2<Animal>("select..");
有更好的方法吗?似乎DapperExtensions在AutoMapper中有这样的东西,但我不清楚它是否适用于SqlMapper.Query()。
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;