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

使用AutoMapper映射SQLite通用数据返回空列表,映射失败求助

解决AutoMapper从SQLite DataReader映射到IEnumerable失败的问题

看起来你遇到的是AutoMapper处理IDataReader映射时的常见配置问题,我来帮你一步步排查:

1. 首先,启用AutoMapper的DataReader映射支持

这是最容易忽略的关键步骤!AutoMapper对IDataReader/IDataRecord的映射并非默认开启,必须在配置时明确添加扩展支持:

var cfg = new MapperConfiguration(cfg => {
    // 核心:启用DataReader映射扩展
    cfg.AddDataReaderMapping();
    
    // 你的实体映射配置
    cfg.CreateMap<IDataRecord, Layout>()
        // 若数据库列名与实体属性名不匹配,明确指定映射关系
        .ForMember(dest => dest.LayoutId, opt => opt.MapFrom(src => src["layout_id"]))
        .ForMember(dest => dest.LayoutName, opt => opt.MapFrom(src => src["layout_name"]));
});

// 强烈建议添加这行,提前验证映射配置的正确性,避免运行时才发现错误
cfg.AssertConfigurationIsValid();

// 创建IMapper实例(推荐用实例化对象而非静态Mapper类,避免线程安全和初始化问题)
var mapper = cfg.CreateMapper();

2. 替换静态Mapper.Map为实例化的IMapper

旧版静态Mapper类容易出现初始化不彻底、多线程冲突等问题,改用实例化的IMapper更稳定可靠:

修改你的执行函数:

// 将IMapper作为参数传入(或通过依赖注入容器注入)
public static IEnumerable<T> ExecuteReaderCommand<T>(SQLiteConnection connection, SQLiteCommand command, IMapper mapper) {
    var result = Enumerable.Empty<T>();
    
    try {
        connection.Open();
        command.Connection = connection;
        
        // 务必用using包裹DataReader,确保资源及时释放
        using (var reader = command.ExecuteReader()) {
            // 使用实例化的mapper完成映射
            result = mapper.Map<IEnumerable<T>>(reader);
        }
    } catch (Exception ex) {
        _logger.Error(ex, "Can't execute {command}, with {connection}", command, connection);
    } finally {
        // 检查连接状态后再关闭,避免重复关闭引发异常
        if (connection.State == ConnectionState.Open) {
            connection.Close();
        }
    }
    
    // 额外提示:SQLite对TransactionScope的支持有限,若无需跨连接事务,建议移除该逻辑
    // 若必须保留,需确保SQLite版本支持且连接字符串配置了Enlist=true
    return result;
}

3. 排查映射匹配细节问题

如果仍报Unmapped错误,按以下步骤逐一验证:

  • 列名与属性名匹配:调试时遍历reader.GetName(i)查看返回的数据库列名,确保与ForMember中指定的名称一致(注意大小写,AutoMapper默认区分大小写)。
  • 属性访问权限:Layout类的属性必须是public修饰的,AutoMapper无法映射私有/保护属性。
  • 可空类型处理:若数据库列允许为空,实体对应属性需设为可空类型(如int?而非int),或在映射时添加空值处理逻辑。

4. 额外建议:简化事务逻辑

SQLite对TransactionScope的支持有诸多限制,如果你的操作不需要跨多个连接的事务,建议直接移除该部分代码,避免引入不必要的复杂度。

按以上步骤调整后,应该能解决映射失败的问题。如果还有疑问,可以通过cfg.AssertConfigurationIsValid()输出的错误信息,精准定位未映射的属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:28:02