【问题标题】:Dapper.net how to create a mapDapper.net 如何创建地图
【发布时间】:2012-12-21 12:01:14
【问题描述】:
 public CodeCustomMapper()
  {

    Map(f => f.Name).Column("SName");
    Map(f => f.Name).Column("TName");
    Map(f => f.EmailID).Column("wmail");
    Map(f => f.EmailID).Column("Email");
   }

我想为 dapper.query 函数创建这种映射。
请问有人可以帮忙吗?
我想将自定义列名称映射到实体属性名称。


public class EntityBase
{
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
}

public class Person :EntityBase
{
    public string SecurityAlias{ get; set; }
    public DateTime Identifier{ get; set; }
}

public class EntityBaseMap
{
    public EntityBaseMap()
    {
        var map = new CustomTypeMap<EntityBase>();
        map.Map("CreatingPerson", "CreatedBy");
        map.Map("CreatedDate", "CreatedOn");
        SqlMapper.SetTypeMap(map.Type, map);
    }
}

public class PersonMap
{
    public PersonMap()
    {
        var map = new CustomTypeMap<Person>();
        map.Map("security_alias", "SecurityAlias");
        map.Map("Id", "Identifier");
        SqlMapper.SetTypeMap(map.Type, map);
    }
}

当我这样称呼时:

EntityBaseMap entityBaseMap = new EntityBaseMap();
PersonMap personMap = new PersonMap();

现在,如果我使用 Person 实体,它不会在 person 实体内映射 EntityBase 属性。

【问题讨论】:

    标签: asp.net-mvc-4 dapper


    【解决方案1】:

    基本上,您需要编写ITypeMap 和IMemberMap 实现,其内部可以基于您选择的任何规则(命名约定,例如删除S 等标识符、下划线等;属性;或自定义映射和你的情况一样)。

    这是一个完整的可运行示例,可能会有所帮助:

    using Dapper;
    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Reflection;
    
    class SomeType
    {
        public string Bar { get; set; }
        public int Foo { get; set; }
    }
    
    static class Program
    {
        static Program()
        {
            // only need to do this ONCE
            var oldMap = SqlMapper.GetTypeMap(typeof(SomeType));
            var map = new CustomTypeMap(typeof(SomeType), oldMap);
            map.Map("IFoo", "Foo");
            map.Map("SBar", "Bar");
            SqlMapper.SetTypeMap(map.Type, map);
        }
    
        static void Main()
        {
            using (var conn = new SqlConnection("Server=.;Database=master;Trusted_Connection=true"))
            {
                conn.Open();
    
                var row = conn.Query<SomeType>("select 123 as [IFoo], 'abc' as [SBar]").Single();
                Console.WriteLine(row.Foo);
                Console.WriteLine(row.Bar);
            }
        }
    
        class CustomTypeMap : SqlMapper.ITypeMap
        {
            private readonly Dictionary<string, SqlMapper.IMemberMap> members
                = new Dictionary<string, SqlMapper.IMemberMap>(StringComparer.OrdinalIgnoreCase);
            public Type Type { get { return type; } }
            private readonly Type type;
            private readonly SqlMapper.ITypeMap tail;
            public void Map(string columnName, string memberName)
            {
                members[columnName] = new MemberMap(type.GetMember(memberName).Single(), columnName);
            }
            public CustomTypeMap(Type type, SqlMapper.ITypeMap tail)
            {
                this.type = type;
                this.tail = tail;
            }
            public System.Reflection.ConstructorInfo FindConstructor(string[] names, Type[] types)
            {
                return tail.FindConstructor(names, types);
            }
    
            public SqlMapper.IMemberMap GetConstructorParameter(
                System.Reflection.ConstructorInfo constructor, string columnName)
            {
                return tail.GetConstructorParameter(constructor, columnName);
            }
    
            public SqlMapper.IMemberMap GetMember(string columnName)
            {
                SqlMapper.IMemberMap map;
                if (!members.TryGetValue(columnName, out map))
                { // you might want to return null if you prefer not to fallback to the
                  // default implementation
                    map = tail.GetMember(columnName);
                }
                return map;
            }
        }
        class MemberMap : SqlMapper.IMemberMap
        {
            private readonly MemberInfo member;
            private readonly string columnName;
            public MemberMap(MemberInfo member, string columnName)
            {
                this.member = member;
                this.columnName = columnName;
            }
            public string ColumnName { get { return columnName; } }
            public System.Reflection.FieldInfo Field { get { return member as FieldInfo; } }
            public Type MemberType { get {
                switch (member.MemberType)
                {
                    case MemberTypes.Field: return ((FieldInfo)member).FieldType;
                    case MemberTypes.Property: return ((PropertyInfo)member).PropertyType;
                    default: throw new NotSupportedException();
                }
            } }
            public System.Reflection.ParameterInfo Parameter { get { return null; } }
            public System.Reflection.PropertyInfo Property { get { return member as PropertyInfo; } }
        }
    }
    

    【讨论】:

    • 感谢 Marc 的快速回复。还有一个问题,如果我使用的是 MVC 应用程序,其中我有数据层(我将在其中使用 dapper)。我的问题是我可以在哪里编写你提供的代码,这样我只需在启动时进行一次映射。?
    • @CodeCrusher 最简单的地方是从 global.asax 调用 DAL 中的 Init 方法,在您配置 MVC 路由的位置附近
    • 嗨,Marc,如果我有一个基本实体,代码将不起作用。它没有映射基本实体的属性。即使我正在单独映射基本实体。
    • @CodeCrusher 你能举个例子吗?
    • 公共类客户端:EntityBase。 Entitybase 我正在映射由 u 给出。也分别与客户分开。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2018-03-28
    相关资源
    最近更新 更多