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

C#中如何从多层嵌套Dictionary获取数据(支持无/部分键)

C# 多层嵌套字典的灵活查询实现

我需要在C#中从多层嵌套的Dictionary中获取数据,当前字典结构如下:

static Dictionary<int, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> allOffset = new();

需求

  • 不传入任何键时,获取所有底层的字符串值
  • 传入部分层级的键时,获取对应层级下的所有值

示例数据

{
    (2024, ("B1", ("C1", ("E1", "Employee1")))),
    (2024, ("B1", ("C1", ("E2", "Employee2"))))
}

预期输出

  1. 传入键2024,或2024、B1、C1时,返回两条记录:"Employee1"和"Employee2"
  2. 传入完整键2024、B1、C1、E1时,仅返回"Employee1"
  3. 不传入任何键时,返回两条记录:"Employee1"和"Employee2"

测试数据填充代码

public void FillDummyData()
{
    for (int i = 2022; i <= 2024; i++)
    {
        for (int j = 1; j <= 12; j++)
        {
            for(int k = 1; k <= 7; k++)
            {
                // 假设EmployeeData是封装allOffset添加逻辑的方法
                EmployeeData.Add(i, j.ToString(), k.ToString(), $"{i}-{j}-{k}");
            }
        }
    }
}

之前查过相关资料,但仅覆盖两层嵌套的场景,不确定如何处理4层及更多层的情况。如果嵌套字典无法满足需求,也可以改用其他集合类型。


解决方案

方案一:基于现有嵌套字典实现灵活查询

编写重载方法,根据传入键的数量逐层遍历字典,收集对应层级的所有值:

public static IEnumerable<string> GetValues(int? key1 = null, string key2 = null, string key3 = null, string key4 = null)
{
    // 初始遍历源:最外层字典
    var currentLevel = allOffset.AsEnumerable();

    // 过滤第一层键
    if (key1.HasValue)
    {
        currentLevel = currentLevel.Where(kv => kv.Key == key1.Value);
        if (!currentLevel.Any()) yield break;
    }

    // 进入第二层并过滤
    var level2 = currentLevel.SelectMany(kv => kv.Value.AsEnumerable());
    if (!string.IsNullOrEmpty(key2))
    {
        level2 = level2.Where(kv => kv.Key == key2);
        if (!level2.Any()) yield break;
    }

    // 进入第三层并过滤
    var level3 = level2.SelectMany(kv => kv.Value.AsEnumerable());
    if (!string.IsNullOrEmpty(key3))
    {
        level3 = level3.Where(kv => kv.Key == key3);
        if (!level3.Any()) yield break;
    }

    // 进入第四层并过滤
    var level4 = level3.SelectMany(kv => kv.Value.AsEnumerable());
    if (!string.IsNullOrEmpty(key4))
    {
        level4 = level4.Where(kv => kv.Key == key4);
        if (!level4.Any()) yield break;
    }

    // 返回最终值
    foreach (var kv in level4)
    {
        yield return kv.Value;
    }
}

使用示例:

// 无键查询
var allValues = GetValues().ToList();

// 传入第一层键
var year2024Values = GetValues(2024).ToList();

// 传入前三层键
var specificValues = GetValues(2024, "B1", "C1").ToList();

// 传入完整键
var singleValue = GetValues(2024, "B1", "C1", "E1").ToList();

方案二:改用扁平结构的集合(更推荐,适配多层扩展)

如果后续可能扩展到5、6层嵌套,嵌套字典会大幅提升代码复杂度,建议改用扁平实体类集合,将多层键作为实体属性:

// 定义实体类
public class EmployeeRecord
{
    public int Year { get; set; }
    public string BKey { get; set; }
    public string CKey { get; set; }
    public string EKey { get; set; }
    public string Value { get; set; }
}

// 用List<EmployeeRecord>替代嵌套字典
static List<EmployeeRecord> allRecords = new();

填充数据方法:

public void FillDummyData()
{
    for (int i = 2022; i <= 2024; i++)
    {
        for (int j = 1; j <= 12; j++)
        {
            for(int k = 1; k <= 7; k++)
            {
                allRecords.Add(new EmployeeRecord
                {
                    Year = i,
                    BKey = j.ToString(),
                    CKey = k.ToString(),
                    EKey = $"E{k}", // 补充E层键逻辑
                    Value = $"{i}-{j}-{k}"
                });
            }
        }
    }
}

查询方法:
利用LINQ灵活组合条件,适配任意层级的键查询:

public static IEnumerable<string> GetRecords(int? year = null, string bKey = null, string cKey = null, string eKey = null)
{
    var query = allRecords.AsQueryable();

    if (year.HasValue)
        query = query.Where(r => r.Year == year.Value);
    if (!string.IsNullOrEmpty(bKey))
        query = query.Where(r => r.BKey == bKey);
    if (!string.IsNullOrEmpty(cKey))
        query = query.Where(r => r.CKey == cKey);
    if (!string.IsNullOrEmpty(eKey))
        query = query.Where(r => r.EKey == eKey);

    return query.Select(r => r.Value);
}

该方案优势:

  • 代码可读性、可维护性更高
  • 扩展更多层级时,只需新增实体属性和查询条件
  • 支持更复杂的查询组合(如范围查询、模糊匹配)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:34:56