更新 Entity Framework Core 中的分层数据

Updating Hierarchical Data in Entity Framework Core

提问人:XedDevil 提问时间:11/8/2023 最后编辑:marc_s XedDevil 更新时间:11/8/2023 访问量:38

问:

我正在 Entity Framework Core 中使用分层数据。每条记录或“达析报告”都有一个 SectionCode,表示其在层次结构中的位置,以及一个链接到其父达析报告的 ParentId。

当我删除达析报告时,我想更新同一层次结构级别上所有后续达析报告的 SectionCode,以及它们的子达析报告。但是,我面临着一个问题,即层次结构的所有级别的 SectionCode 都未正确更新。 这是我的代码:

public async Task<ActionResult<Dossier>> DeleteDossier(string sectionCode)
{
    var dossier = await _context.Dossiers.FirstOrDefaultAsync(d => d.SectionCode == sectionCode);
    if (dossier == null) { return NotFound(); }

    // Find all child dossiers
    var childDossiers = _context.Dossiers.Where(d => d.SectionCode.StartsWith(sectionCode) && d.Id != dossier.Id).ToList();

    // Delete all child dossiers
    foreach (var child in childDossiers)
    {
        await DeleteDossier(child.SectionCode);
    }

    // Delete parent dossier
    _context.Dossiers.Remove(dossier);

    // Update SectionCode, ParentId and OrderNumber of nodes that follow the deleted one at the same hierarchy level
    var subsequentDossiers = _context.Dossiers.Where(d => d.ParentId == dossier.ParentId && d.OrderNumber > dossier.OrderNumber).ToList();

    // Collect all dossiers that need updating into a list
    List<Dossier> dossiersToUpdate = new List<Dossier>();

    foreach (var subsequentDossier in subsequentDossiers)
    {
        subsequentDossier.OrderNumber--;
        var sectionCodeParts = subsequentDossier.SectionCode.Split('.');
        sectionCodeParts[sectionCodeParts.Length - 1] = subsequentDossier.OrderNumber.ToString();
        subsequentDossier.SectionCode = string.Join('.', sectionCodeParts);

        // Add subsequentDossier to the update list
        dossiersToUpdate.Add(subsequentDossier);
    }

    // Update SectionCode for all dossiers in the list
    foreach (var dossiers in dossiersToUpdate)
    {
        UpdateChildDossiers(dossiers);
    }

    await _context.SaveChangesAsync();

    return NoContent();
}

private void UpdateChildDossiers(Dossier parentDossier)
{
    var childDossiers = _context.Dossiers.Where(d => d.ParentId == parentDossier.Id).ToList();
    foreach (var childDossier in childDossiers)
    {
        var childSectionCodeParts = childDossier.SectionCode.Split('.');
        childSectionCodeParts[childSectionCodeParts.Length - 2] = parentDossier.OrderNumber.ToString();
        childDossier.SectionCode = string.Join('.', childSectionCodeParts);

        // Recursive update of SectionCode for child nodes of the current dossier
        UpdateChildDossiers(childDossier);
    }
}

数据会更新,但不会在层次结构的所有级别更新

第 2 节 DELETE 之前的 JSON:

[
  {
    "id": 1,
    "parentId": null,
    "orderNumber": 1,
    "sectionCode": "1",
    "name": "string"
  },
  {
    "id": 2,
    "parentId": 1,
    "orderNumber": 1,
    "sectionCode": "1.1",
    "name": "string"
  },
  {
    "id": 43,
    "parentId": null,
    "orderNumber": 2,
    "sectionCode": "2",
    "name": "string"
  },
  {
    "id": 44,
    "parentId": 43,
    "orderNumber": 1,
    "sectionCode": "2.1",
    "name": "string"
  },
  {
    "id": 45,
    "parentId": 43,
    "orderNumber": 2,
    "sectionCode": "2.2",
    "name": "string"
  },
  {
    "id": 46,
    "parentId": null,
    "orderNumber": 3,
    "sectionCode": "3",
    "name": "string"
  },
  {
    "id": 47,
    "parentId": 46,
    "orderNumber": 1,
    "sectionCode": "3.1",
    "name": "string"
  },
  {
    "id": 48,
    "parentId": 46,
    "orderNumber": 2,
    "sectionCode": "3.2",
    "name": "string"
  },
  {
    "id": 49,
    "parentId": 48,
    "orderNumber": 1,
    "sectionCode": "3.2.1",
    "name": "string"
  }
]

删除后:

[
  {
    "id": 1,
    "parentId": null,
    "orderNumber": 1,
    "sectionCode": "1",
    "name": "string"
  },
  {
    "id": 2,
    "parentId": 1,
    "orderNumber": 1,
    "sectionCode": "1.1",
    "name": "string"
  },
  {
    "id": 46,
    "parentId": null,
    "orderNumber": 2,
    "sectionCode": "2",
    "name": "string"
  },
  {
    "id": 47,
    "parentId": 46,
    "orderNumber": 1,
    "sectionCode": "2.1",
    "name": "string"
  },
  {
    "id": 48,
    "parentId": 46,
    "orderNumber": 2,
    "sectionCode": "2.2",
    "name": "string"
  },
  {
    "id": 49,
    "parentId": 48,
    "orderNumber": 1,
    "sectionCode": "3.2.1",
    "name": "string"
  }
]

如您所见,第 3 节尚未完全更新其编号。

C# asp.net json asp.net-web-api 实体框架核心

评论

1赞 Steve Py 11/8/2023
在插入或删除后更新层次结构并非易事,最好在数据库本身中完成,而不是使用 EF。问题在于,当您删除主分支并且需要向前移动大量行时,“触摸表面”可能是表格的大部分内容。看一看 stackoverflow.com/questions/62959413/...

答: 暂无答案