You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dapper SetTypeMap导致DapperExtensions ClassMapper失效问题咨询

Why Dapper Extensions Fails to Map User Class After Calling SqlMapper.SetTypeMap()

Yep, you’re exactly right—calling Dapper.SqlMapper.SetTypeMap(typeof(User), new UserMapper()) does override the default type mapping configuration that Dapper Extensions depends on. Here’s why this happens and how to fix it:

Why This Occurs

Dapper Extensions builds directly on top of Dapper’s core mapping system. When you set a custom ITypeMap globally for a type, you’re replacing Dapper’s default type resolver (which Dapper Extensions relies on to load its own ClassMapper configurations). Dapper will prioritize your custom ITypeMap over any mappings registered by Dapper Extensions, so when you call cn.Get<User>(id), Dapper Extensions can’t access its own column-to-property mappings anymore—hence you get default values for all properties.

Solutions to Make Them Coexist

Modify your UserMapper to wrap both Dapper’s default type map and Dapper Extensions’ mappings, instead of replacing them entirely. This way, your custom logic runs alongside the existing Dapper Extensions configuration.

Here’s an example implementation:

public class UserMapper : SqlMapper.ITypeMap
{
    private readonly ITypeMap _underlyingTypeMap;

    public UserMapper()
    {
        // Get the existing type map that Dapper Extensions set up
        _underlyingTypeMap = SqlMapper.GetTypeMap(typeof(User)) 
                             ?? new DefaultTypeMap(typeof(User));
    }

    // Delegate to the underlying map first, then apply custom logic
    public ConstructorInfo FindConstructor(string[] names, Type[] types)
    {
        return _underlyingTypeMap.FindConstructor(names, types);
    }

    public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
    {
        return _underlyingTypeMap.GetConstructorParameter(constructor, columnName);
    }

    public SqlMapper.IMemberMap GetMember(string columnName)
    {
        // Check the existing mapping first
        var memberMap = _underlyingTypeMap.GetMember(columnName);
        if (memberMap != null)
            return memberMap;

        // Add your custom column-to-property mappings here
        return columnName.ToLower() switch
        {
            "user_id" => new CustomMemberMap(typeof(User).GetProperty(nameof(User.Id))),
            "user_fullname" => new CustomMemberMap(typeof(User).GetProperty(nameof(User.FullName))),
            _ => null
        };
    }

    public ConstructorInfo[] GetConstructors()
    {
        return _underlyingTypeMap.GetConstructors();
    }
}

// Helper class to implement IMemberMap for custom mappings
public class CustomMemberMap : SqlMapper.IMemberMap
{
    public Type MemberType => _property.PropertyType;
    public string ColumnName { get; }
    public MemberInfo Member => _property;
    public ParameterInfo Parameter { get; }

    private readonly PropertyInfo _property;

    public CustomMemberMap(PropertyInfo property)
    {
        _property = property;
    }
}

2. Avoid Global Type Mapping (Use Per-Query Mappings)

If your custom mapping only applies to specific queries, skip the global SetTypeMap and instead specify the type map directly when executing Dapper queries. This leaves Dapper Extensions’ mappings intact for its own operations:

// For Dapper queries that need your custom mapping
var users = cn.Query<User>(sql, typeMap: new UserMapper());

// Dapper Extensions calls like cn.Get<User>(id) will still use their own mappings

Key Takeaway

Dapper’s global type map is a single point of configuration—replacing it overrides all other mapping sources, including Dapper Extensions. By wrapping the existing type map in your custom ITypeMap implementation, you preserve Dapper Extensions’ functionality while adding your own custom logic.

内容的提问来源于stack exchange,提问作者Daniele Arrighi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:40:15