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

如何使用C#/Dapper插入多层嵌套数据?

批量嵌套数据插入问题(基于Dapper和UDT)

我定义了以下三层嵌套的类结构:

public class SignUpList {
    public int? SignUpListId { get; set; }
    public IEnumerable<SignUpItem> Items { get; set; }
}

public class SignUpItem {
    public int? SignUpItemId { get; set; }
    public int? SignUpListId { get; set; }
    public IEnumerable<ItemPerson> Persons { get; set; }
}

public class ItemPerson {
    public int? ItemPersonId { get; set; }
    public int? SignUpItemId { get; set; }
    public int PersonId { get; set; } //外键关联其他表
}

场景类似Sign Up Genius:比如创建一个名为「Classroom Party」的报名列表,列表下有「Plates」「Forks」「Napkins」等报名项,每个项最多允许4人报名。

现在的需求是:当调用SignUpList的API端点时,通过**UDT(用户定义类型)**作为参数,把整个嵌套结构的所有记录合并到数据库的现有表中。

核心问题

首次插入时,ItemPerson没有ItemPersonId,且无法直接关联对应的SignUpItemId——因为SignUpItemId是数据库生成的自增ID,插入前无法预知。

目前能实现但存在痛点的方案:

  • 单条循环插入:先插入SignUpList获取SignUpListId,再循环插入每个SignUpItem并获取SignUpItemId,最后批量插入ItemPerson。代码大致如下:

    var listId = ExecuteScalar<int>("dbo.SaveList", parameters, commandType: StoredProcedure);
    
    foreach (var item in SignUpList.Items) {
        var itemId = ExecuteScalar<int>("[dbo].[SaveItem]", parameters); //假设参数已正确构造
        // 收集ItemPerson并填充到UDT的DataTable中
    }
    _ = ExecuteAsync("dbo.SavePersons", udtParameters);
    

    缺点:数据库操作次数过多,性能开销大。

  • 批量插入SignUpItem但无法关联Person:尝试一次性批量插入所有SignUpItem,但插入后无法将生成的SignUpItemId和对应的ItemPerson关联起来——因为批量返回的ID列表无法和原列表中的项一一对应,会丢失人员与项的关联关系。

  • 行号伪ID关联:考虑给父项添加临时的「行号」字段作为伪ID,插入时通过行号关联子项,最后再清理这个字段。这种方式能减少数据库连接次数,但需要修改表结构或UDT定义。

疑问

  1. 是否有我忽略的Dapper特性,可以更高效地处理这种嵌套结构的批量插入+ID关联问题?
  2. 是否有更合适的数据结构设计,既能满足三层嵌套的业务需求,又能简化数据库操作?(曾考虑过把ItemPerson序列化为SignUpItem的JSON字段,但需要对人员数据进行查询,所以这个方案不可行)

注:由于应用特性限制,无法拆分列表和项的保存流程,必须一次性完成整个嵌套结构的合并操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:15:58