首页 > 解决方案 > 如何使用 Linq 过滤具有子列表的项目列表以删除 C# 中不允许的项目?

问题描述

我有一个两层列表对象,我正在尝试将期望数据选择到另一个列表中。请参考以下型号和样品数据。

在此示例中,我只想从列表中选择“user_access==true”,但无法正确选择。“选项”部分中的数据未过滤。
我尝试过的,

menudata = menusetup.Where(e => e.user_access == true)
                    .Where(e => e.Options.Any(s => s.user_access == true)).ToList();

请指教。

谢谢

private class MenuModel
{
    public string Id { get; set; } // menu type
    public List<MenuModel> Options { get; set; }
    public string Value { get; set; }
    public string imgUrl { get; set; }
    public string Count { get; set; }
    public string About { get; set; }
    public bool user_access { get; set; } = false;
    public bool vendor_access { get; set; } = false;
}

和样本列表数据

private List<MenuModel> menusetup = new List<MenuModel>
{
    new MenuModel {
        Id = "menu",
        Value = "Products",
        user_access = true,
        Options = new List<MenuModel>
        {
            new MenuModel { Value= "Account Group", imgUrl= "\accountgroup", user_access=false },
            new MenuModel { Value= "Angular", imgUrl= "angular", user_access=true },
            new MenuModel { Value= "ASP.NET Core", imgUrl= "core", user_access=false },
            new MenuModel { Value= "ASP.NET MVC", imgUrl= "mvc" , user_access=true}
        }
    },
    new MenuModel {
        Id = "menu",
        Value = "Services",
        Options = new List<MenuModel>
        {
            new MenuModel { Value= "Application Development", Count= "1200+" },
            new MenuModel { Value= "Maintenance & Support", Count= "3700+" },
            new MenuModel { Value= "Quality Assurance" },
            new MenuModel { Value= "Cloud Integration", Count= "900+" }
        }
    }
}

附加信息,我对新列表的期望如下

{ 
  Id = "menu",
  Value = "Products",
  user_access = true,
  Options
  {
    { Value= "Angular", imgUrl= "angular", user_access=true },
    { Value= "ASP.NET MVC", imgUrl= "mvc" , user_access=true}
  }
}

标签: c#listlinq

解决方案


要求:从 menuSetup 序列中查询所有具有真正 UserAccess 的 MenuModel,每个 MenuModel 及其具有真正 UserAccess 的 Options。

var result = menuSetups.Where(menuSetup => menuSetup.UserAccess)
    .Select(menuSetup => new
    {
        Id = menuSetup.Id,
        Value = menuSetup.Value,
        UserAccess = true,         // do you really need this? you already know that it's true

        Options = menuSetup.Options
            .Where(option => option.UserAccess)
            .Select(option = > new
            {
                Id = option.Id,
                Value = option.Value,
                UserAccess = true,
            })
            .ToList(),
    });

换句话说:从 menuSetups 的序列中,只保留那些具有真值的 menuSetup 用于 UserAccess。从每个剩余的 menuSetup 中获取属性...

仅保留每个剩余 menuSetup 的那些对 UserAccess 具有真值的选项。并选择属性...,

几个建议

如果您只选择您实际计划使用的属性,效率会更高。不要选择外键,也不要选择您已经知道其值的其他值。

不要使用“UserAccess == true”。它给别人的印象是你不懂布尔值。这种编码风格导致:

if (a == true)
    b = true;
else
    b = false;

代替:

b = a;

推荐阅读