在 Linq 中使用另一个列表中的项目搜索列表

Posted

技术标签:

【中文标题】在 Linq 中使用另一个列表中的项目搜索列表【英文标题】:In Linq search a list using items in another list 【发布时间】:2022-01-21 19:48:04 【问题描述】:

我有一个用户拥有的角色列表

List<Role> userRoles; // this is a list of roles

然后我的文件夹具有一个或多个关联角色并且可以访问 Folders.Roles。

我想返回与文件夹中的字段匹配并且在 userRoles 列表中的子角色列表中也有角色的文件夹列表。

我基本上可以使用一些 foreach 语句来做我想做的事......

bool hasRole = false;
            List<Folder> folders2 = _customerPortalDbContext.Folders.Where(f => f.ParentFolderId == Guid.Empty).ToList();
            foreach(Folder f in folders2)
            
                foreach (Role role in f.Roles)
                
                  if(  roles.Any(r => r.Id == role.Id)) hasRole = true;
                
            

但我觉得我过去曾使用一些聪明的 Linq 代码看到或做过类似的事情,所以希望这可能吗?类似的东西

IQueryable<Folder> folders = _customerPortalDbContext.Folders.Where(f => f.FolderType == "FolderType") 
&& f.Roles.RoleId.<<Compare to roles in List of roles>>);

【问题讨论】:

【参考方案1】:

假设你有这样的课程:

    class Folder
    
        public Guid ParentFolderId  get; set; 
        public List<Role> Roles  get; set; 
    

    class Role
    
        public int Id  get; set; 
    

还有你的两个清单:

List<Folder> folders2
List<Role> userRoles = new List<Role>();

我想,你可以试试这样的:

bool hasRole = folders2
    .Where(f=>f.ParentFolderId == Guid.Empty) // only gets folders with no parent
    .SelectMany(f => f.Roles) // gets all roles from all folders
    .Any(r => userRoles.Any(ur => ur.Id == r.Id)); // checks if userRoles contains a role with the same Id

如果您在 Role 类中覆盖 Equals 方法,我认为您也可以使用 Contains 而不是 Any。这可以提高可读性,但您需要小心,因为它会在每次比较时覆盖它。

【讨论】:

【参考方案2】:

获取ID列表并使用Contains

idList = userRoles.Select(r => r.Id).ToList();

IQueryable<Folder> folders = _customerPortalDbContext.Folders
    .Where(f => f.FolderType == "FolderType" 
             && f.Roles.Any(r => idList.Contains(r.RoleId)));

Contains 将转换为IS IN SQL 表达式,使用您的 ID 列表作为一组常量值。

【讨论】:

以上是关于在 Linq 中使用另一个列表中的项目搜索列表的主要内容,如果未能解决你的问题,请参考以下文章

c# 在 LINQ 查询返回的列表中查找项目并将其值与列表中的另一个项目进行比较

在一个列表中查找不在另一个列表中的项目[重复]

使用Linq根据每个项目中的值的总和对列表进行排序

如何使用 Linq 根据另一个列表过滤列表?

根据另一个列表中的真实条件从通用列表中选择项目

另一个列表中列表中项目的扩展方法[重复]