Custom mapping in Dapper

后端 未结 3 922
别跟我提以往
别跟我提以往 2021-02-04 12:03

I\'m attempting to use a CTE with Dapper and multi-mapping to get paged results. I\'m hitting an inconvenience with duplicate columns; the CTE is preventing me from having to Na

3条回答
  •  自闭症患者
    2021-02-04 12:49

    You can map a column name with another attribute using the ColumnAttributeTypeMapper.

    See my first comment on the Gist for further details.

    You can do the mapping like

    public class Site
    {
        public int SiteID { get; set; }
        [Column("SiteName")]
        public string Name { get; set; }
        public string Description { get; set; }
        public List Locations { get; internal set; }
    }
    
    public class Location
    {
        public int LocationID { get; set; }
        [Column("LocationName")]
        public string Name { get; set; }
        [Column("LocationDescription")]
        public string Description { get; set; }
        public Guid ReportingID { get; set; }
        [Column("LocationSiteID")]
        public int SiteID { get; set; }
    }
    

    Mapping can be done using either of the following 3 methods

    Method 1

    Manually set the custom TypeMapper for your Model once as:

    Dapper.SqlMapper.SetTypeMap(typeof(Site), new ColumnAttributeTypeMapper());
    Dapper.SqlMapper.SetTypeMap(typeof(Location), new ColumnAttributeTypeMapper());
    

    Method 2

    For class libraries of .NET Framework >= v4.0, you can use PreApplicationStartMethod to register your classes for custom type mapping.

    using System.Web;
    using Dapper;
    
    [assembly: PreApplicationStartMethod(typeof(YourNamespace.Initiator), "RegisterModels")]
    
    namespace YourNamespace
    {
        public class Initiator
        {
            private static void RegisterModels()
            {
                 SqlMapper.SetTypeMap(typeof(Site), new ColumnAttributeTypeMapper());
                 SqlMapper.SetTypeMap(typeof(Location), new ColumnAttributeTypeMapper());
                 // ...
            }
        }
    }
    

    Method 3

    Or you can find the classes to which ColumnAttribute is applied through reflection and set type mappings. This could be a little slower, but it does all the mappings in your assembly automatically for you. Just call RegisterTypeMaps() once your assembly is loaded.

        public static void RegisterTypeMaps()
        {
            var mappedTypes = Assembly.GetAssembly(typeof (Initiator)).GetTypes().Where(
                f =>
                f.GetProperties().Any(
                    p =>
                    p.GetCustomAttributes(false).Any(
                        a => a.GetType().Name == ColumnAttributeTypeMapper.ColumnAttributeName)));
    
            var mapper = typeof(ColumnAttributeTypeMapper<>);
            foreach (var mappedType in mappedTypes)
            {
                var genericType = mapper.MakeGenericType(new[] { mappedType });
                SqlMapper.SetTypeMap(mappedType, Activator.CreateInstance(genericType) as SqlMapper.ITypeMap);
            }
        }
    

提交回复
热议问题