Dapper. Map to SQL Column with spaces in column names

后端 未结 3 1178
灰色年华
灰色年华 2020-12-30 01:46

I\'ve managed to get something up and running today as small sandbox/POC project, but have seemed to bump my head on one issue...

Question:

相关标签:
3条回答
  • 2020-12-30 02:19

    There's a nuget package Dapper.FluentMap that allows you to add column name mappings (including spaces). It's similar to EntityFramework.

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

    see https://github.com/henkmollema/Dapper-FluentMap for more.

    0 讨论(0)
  • 2020-12-30 02:20

    One option here would be to go via the dynamic / non-generic API, and then fetch the values out via the IDictionary<string,object> API per row, but that might be a bit tedious.

    As an alternative, you can create a custom mapper, and tell dapper about it; for example:

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

    with:

    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; }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-30 02:22

    I had a similar problem when trying to get mapped results from a call to the system sp_spaceused procedure. Marc's code didn't quite work for me as it complained about not being able to find a default constructor. I also made my version generic so it could theoretically be re-used. This may not be the fastest performing piece of code, but it works for me and in our situation these calls are made infrequently.

    class TitleCaseMap<T> : 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; }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题