小巧玲珑。 映射到SQL列,列名称中包含空格

我已经设法在今天作为小沙盒/ POC项目获得了一些东西,但似乎在一个问题上让我头脑发热……

题:

有没有办法让dapper映射到带有空格的SQL列名。

作为我的结果集,我有一些这样的效果。

例如:

SELECT 001 AS [Col 1], 901 AS [Col 2], 00454345345345435349 AS [Col 3], 03453453453454353458 AS [Col 4] FROM [Some Schema].[Some Table] 

我的class级看起来像这样

  public class ClassA { public string Col1 { get; set; } public string Col2 { get; set; } ///... etc } 

我的实现目前看起来像这样

  public Tuple<IList, IList> QueryMultiple(object parameters) { List output1; List output2; using (var data = this.Connection.QueryMultiple(this.GlobalParameter.RpcProcedureName, parameters, CommandType.StoredProcedure)) { output1 = data.Read().ToList(); output2 = data.Read().ToList(); } var result = new Tuple<IList, IList>(output1, output2); return result; } 

注意:SQL无法以任何方式进行修改。

目前我正在经历一个短小精悍的代码,我唯一可以预见的解决方案是添加一些代码来“说服”列比较,但到目前为止没有太多运气。

我在StackOverflow上看到有些东西像dapper扩展,但是我希望我可以在不添加扩展的情况下完成这项工作,如果没有的话。 我会采取最快捷的方式来实施。

这里的一个选择是通过动态/非genericsAPI,然后通过每行IDictionary API获取值,但这可能有点乏味。

作为替代方案,您可以创建一个自定义映射器,并告诉dapper它; 例如:

 SqlMapper.SetTypeMap(typeof(ClassA), new RemoveSpacesMap()); 

有:

 class RemoveSpacesMap : Dapper.SqlMapper.ITypeMap { System.Reflection.ConstructorInfo SqlMapper.ITypeMap.FindConstructor(string[] names, Type[] types) { return null; } SqlMapper.IMemberMap SqlMapper.ITypeMap.GetConstructorParameter(System.Reflection.ConstructorInfo constructor, string columnName) { return null; } SqlMapper.IMemberMap SqlMapper.ITypeMap.GetMember(string columnName) { var prop = typeof(ClassA).GetProperty(columnName.Replace(" ", "")); return prop == null ? null : new PropertyMemberMap(columnName, prop); } class PropertyMemberMap : Dapper.SqlMapper.IMemberMap { private string columnName; private PropertyInfo property; public PropertyMemberMap(string columnName, PropertyInfo property) { this.columnName = columnName; this.property = property; } string SqlMapper.IMemberMap.ColumnName { get { throw new NotImplementedException(); } } System.Reflection.FieldInfo SqlMapper.IMemberMap.Field { get { return null; } } Type SqlMapper.IMemberMap.MemberType { get { return property.PropertyType; } } System.Reflection.ParameterInfo SqlMapper.IMemberMap.Parameter { get { return null; } } System.Reflection.PropertyInfo SqlMapper.IMemberMap.Property { get { return property; } } } } 

有一个nuget包Dapper.FluentMap ,允许您添加列名映射(包括空格)。 它与EntityFramework类似。

 // Entity class. public class Customer { public string Name { get; set; } } // Mapper class. public class CustomerMapper : EntityMap { public CustomerMapper() { Map(p => p.Name).ToColumn("Customer Name"); } } // Initialise like so - FluentMapper.Initialize(a => a.AddMap(new CustomerMapper())); 

有关更多信息,请参阅https://github.com/henkmollema/Dapper-FluentMap 。

尝试从调用系统sp_spaceused过程获取映射结果时,我遇到了类似的问题。 Marc的代码对我来说并不适合,因为它抱怨无法找到默认构造函数。 我也使我的版本通用,所以它理论上可以重复使用。 这可能不是执行速度最快的代码,但它适用于我,在我们的情况下,这些调用很少发生。

 class TitleCaseMap : SqlMapper.ITypeMap where T: new() { ConstructorInfo SqlMapper.ITypeMap.FindConstructor(string[] names, Type[] types) { return typeof(T).GetConstructor(Type.EmptyTypes); } SqlMapper.IMemberMap SqlMapper.ITypeMap.GetConstructorParameter(ConstructorInfo constructor, string columnName) { return null; } SqlMapper.IMemberMap SqlMapper.ITypeMap.GetMember(string columnName) { string reformattedColumnName = string.Empty; foreach (string word in columnName.Replace("_", " ").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) { reformattedColumnName += char.ToUpper(word[0]) + word.Substring(1).ToLower(); } var prop = typeof(T).GetProperty(reformattedColumnName); return prop == null ? null : new PropertyMemberMap(prop); } class PropertyMemberMap : SqlMapper.IMemberMap { private readonly PropertyInfo _property; public PropertyMemberMap(PropertyInfo property) { _property = property; } string SqlMapper.IMemberMap.ColumnName { get { throw new NotImplementedException(); } } FieldInfo SqlMapper.IMemberMap.Field { get { return null; } } Type SqlMapper.IMemberMap.MemberType { get { return _property.PropertyType; } } ParameterInfo SqlMapper.IMemberMap.Parameter { get { return null; } } PropertyInfo SqlMapper.IMemberMap.Property { get { return _property; } } } }