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

C#递归方法重复调用时重复插入ChangeLog数据求助

问题分析与修复方案

你的重复插入问题核心源于三个关键逻辑漏洞:

  1. 从GitLab API获取的ChangeLogData尚未插入数据库,Id字段为空或为默认值,用pc.Id == cld.Id做过滤完全无效——新数据的数据库自增ID还未生成,根本无法与已有记录匹配。
  2. 递归过程中传递的previousChangelog始终是初始的旧数据集合,没有包含递归时新插入的记录,导致后续调用仍会把已插入的数据判定为新数据。
  3. 开头的版本检查逻辑不准确:仅判断当前版本是否存在任意一条变更记录就终止处理,但实际场景中可能该版本下还有未插入的记录,或者这个判断逻辑本身不符合批量插入的需求。

修复步骤与代码示例

1. 改用GitLab原生唯一标识过滤

找到ChangeLogData中来自GitLab的唯一字段(比如CommitHash、GitLabCommitId这类Git返回的全局唯一值),用这个字段替代数据库自增Id做存在性判断——这是确保过滤有效的核心前提。

2. 递归时更新已存在记录集合

每次插入新数据后,将其合并到已存在的记录列表中,传递给后续递归调用,确保后续判断能覆盖所有已插入的内容。

3. 调整递归逻辑顺序

先处理后续版本并更新已存在记录集合,再处理当前版本,避免遗漏新插入的数据。

修改后的代码:

private async Task PopulateChangeLogDataEntityRecursive(IEnumerable<AppVersionData> versions, IReadOnlyList<ChangeLogData> existingChangelogs)
{
    var currentAppVersion = versions.FirstOrDefault();
    if (currentAppVersion == null)
    {
        return;
    }

    var previousVersions = versions.Skip(1);
    // 先处理后续版本,同步更新已存在的记录集合
    var updatedExistingChangelogs = new List<ChangeLogData>(existingChangelogs);
    await PopulateChangeLogDataEntityRecursive(previousVersions, updatedExistingChangelogs);

    var previousAppVersion = previousVersions.FirstOrDefault();
    if (previousAppVersion != null)
    {
        var changeLogDataList = await _gitLabClient.GetChangeLogData(previousAppVersion.Version, currentAppVersion.Version);
        foreach (var changeLogData in changeLogDataList)
        {
            changeLogData.AppVersionId = currentAppVersion.Id;
        }

        // 替换为你实际使用的GitLab唯一标识字段(比如CommitHash)
        var newChangeLogs = changeLogDataList
            .Where(cld => !updatedExistingChangelogs.Any(pc => pc.CommitHash == cld.CommitHash))
            .ToList();

        if (newChangeLogs.Any())
        {
            await _repository.BulkInsertAsync(newChangeLogs);
            // 将新插入的记录加入已存在集合,供后续递归判断使用
            updatedExistingChangelogs.AddRange(newChangeLogs);
        }
    }
}

额外建议

  • 给GitLab唯一标识字段添加数据库唯一约束,从底层防止重复插入,这是最后一道可靠防线。
  • 如果你的ChangeLogData实体还没有存储GitLab的唯一标识,需要先修改实体类和数据库表,添加对应的字段(比如CommitHash)——这是解决问题的必要前提。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:40:22