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

使用ABP Dapper解析ExtraProperties时遇类型转换错误求助

Dapper映射ExtraPropertyDictionary失败的解决方法

问题场景

执行全表查询代码时抛出转换异常:

(dbConnection.QueryAsync("select * from AbpUsers", transaction: await GetDbTransactionAsync())).ToList()

异常信息:

System.Data.DataException: 'Error parsing column 2 (ExtraProperties={} - String)'
InvalidCastException: Invalid cast from 'System.String' to 'Volo.Abp.Data.ExtraPropertyDictionary'

但单独查询ExtraProperties列时代码正常:

(dbConnection.QueryAsync("select ExtraProperties from AbpUsers", transaction: await GetDbTransactionAsync())).ToList()

原因分析

数据库中ExtraProperties存储的是JSON字符串,而实体类(如IdentityUser)中该属性类型为ExtraPropertyDictionary。单独查询时Dapper直接返回字符串,不会触发类型转换;全表查询时Dapper尝试自动映射实体类,但缺少字符串到ExtraPropertyDictionary的转换逻辑,导致失败。

解决办法

1. 全局注册Dapper类型转换器

编写自定义类型转换器,让Dapper处理字符串与ExtraPropertyDictionary的双向转换:

using Dapper;
using Newtonsoft.Json;
using Volo.Abp.Data;

public class ExtraPropertyDictionaryTypeHandler : SqlMapper.TypeHandler<ExtraPropertyDictionary>
{
    public override ExtraPropertyDictionary Parse(object value)
    {
        if (value is string json)
        {
            return string.IsNullOrEmpty(json) 
                ? new ExtraPropertyDictionary() 
                : JsonConvert.DeserializeObject<ExtraPropertyDictionary>(json);
        }
        return new ExtraPropertyDictionary();
    }

    public override void SetValue(System.Data.IDbDataParameter parameter, ExtraPropertyDictionary value)
    {
        parameter.Value = JsonConvert.SerializeObject(value);
    }
}

// 在应用启动时注册(比如Program.cs或Startup.cs)
SqlMapper.AddTypeHandler(new ExtraPropertyDictionaryTypeHandler());

2. 查询时手动映射

如果不需要全局转换,可在查询后手动转换属性:

var queryResult = await dbConnection.QueryAsync("select * from AbpUsers", transaction: await GetDbTransactionAsync());
var users = queryResult.Select(row => new IdentityUser
{
    Id = row.Id,
    UserName = row.UserName,
    Email = row.Email,
    // 映射其他属性
    ExtraProperties = JsonConvert.DeserializeObject<ExtraPropertyDictionary>(row.ExtraProperties.ToString())
}).ToList();

3. 确认实体类属性配置

确保IdentityUser中的ExtraProperties属性已正确定义为ExtraPropertyDictionary类型,无需额外特性(Dapper不依赖ABP框架特性)。

内容的提问来源于stack exchange,提问作者Quyết Vũ Văn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:45:39