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

使用Dapper关联查询时Event列表未填充的问题排查

解决Dapper关联查询中Events列表未填充的问题

你的问题主要出在Dapper的splitOn参数配置和结果合并逻辑上,我来一步步帮你修正:

1. 修正splitOn参数的错误设置

你把splitOn写成了"Id, UserId",这不符合Dapper的规则。splitOn的作用是告诉Dapper:结果集中从哪一列开始,要映射到第二个实体(这里是Event)。你的查询结果里,u.Id属于User的属性,后续的e.UserId、e.EventText都是Event的属性,所以只需要把splitOn设为"UserId"就足够了。

2. 处理重复User的合并问题

Dapper的Query<User, Event, User>方法会为每一行返回一个User对象——也就是说,如果一个用户有3条Event记录,会返回3个相同Id的User,每个User的Events列表里只有一条Event。这时候需要我们手动合并相同Id的User,把所有关联的Event汇总到同一个列表中。

3. 处理LEFT JOIN返回的null Event

因为用了LEFT JOIN,没有关联Event的用户对应的e会是null,直接执行Add会报错,所以要先判断Event是否不为null再添加。

修正后的完整代码

// 补充查询User和Event的完整字段,确保对象属性映射完整
var sql = @"SELECT u.Id, u.Name, u.Department, 
                   e.Id AS EventId, e.UserId, e.EventText, 
                   e.StartTime, e.EndTime, e.Day, e.ColorIdentifier, e.Week
            FROM cpc.PLANNING_TOOL_USERS u 
            LEFT JOIN cpc.PLANNING_TOOL_EVENTS e ON u.Id=e.UserId";

// 用字典跟踪已创建的User,避免重复实例化
var userDict = new Dictionary<int, User>();

SqlMapper.Query<User, Event, User>(
    connection, 
    sql, 
    (user, ev) => 
    {
        // 如果字典里没有当前用户,初始化并加入字典
        if (!userDict.TryGetValue(user.Id, out var existingUser))
        {
            existingUser = user;
            existingUser.Events = new List<Event>();
            userDict.Add(existingUser.Id, existingUser);
        }
        // 仅当Event不为null时添加(兼容无Event的用户)
        if (ev != null)
        {
            existingUser.Events.Add(ev);
        }
        return existingUser;
    },
    splitOn: "EventId" // 用别名EventId区分User和Event的Id字段,避免映射混淆
);

// 最终得到的是所有用户,每个用户的Events列表已正确填充
var finalUsers = userDict.Values.ToList();

额外说明

  • 我在SQL里补充了User和Event的完整字段,这样映射出来的对象属性才会完整,你可以根据实际需求调整查询字段。
  • 用EventId作为splitOn的列,是因为User和Event都有Id字段,用别名区分能避免Dapper映射时的混淆,这是个实用的小技巧。
  • 借助字典跟踪已创建的User,确保同一个用户只被初始化一次,所有关联的Event都被归集到同一个列表中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:00:10