在 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 中使用另一个列表中的项目搜索列表的主要内容,如果未能解决你的问题,请参考以下文章