【发布时间】:2021-04-06 11:27:46
【问题描述】:
我对使用 LINQ 有点陌生,遇到了一个我似乎无法解决的问题。
所以我基本上需要过滤嵌套在三个列表中的对象的属性。数据(作为 JSON)如下所示:
[
{
"userName":"John",
"resourceTypeUserVms":[
{
"name":"Administration",
"description":null,
"resourceUserVms":[
{
"policyUserVm":{
"policyName":"admin",
"priority":0,
"metaHash":"abc123",
"policySetName":"Admin",
"policySetDescription":""
},
"accessType":"Administration",
"accessDescription":null,
"metaData":"{\"Name\":\"Admin\"}"
},
{
"policyUserVm":{
"policyName":"test",
"priority":0,
"metaHash":"abc123",
"policySetName":"Test",
"policySetDescription":""
},
"accessType":"Administration",
"accessDescription":null,
"metaData":"{\"Name\":\"test123\"}"
}
]
},
{
"name":"Database",
"description":null,
"resourceUserVms":[
{
"policyUserVm":{
"policyName":"read_x",
"priority":0,
"metaHash":"def456",
"policySetName":"Test",
"policySetDescription":""
},
"accessType":"read",
"accessDescription":null,
"metaData":"{\"Server\":\"srv\",\"Name\":\"test\"}"
}
]
},
{
"name":"Configuration",
"description":null,
"resourceUserVms":[
{
"policyUserVm":{
"policyName":"readc",
"priority":0,
"metaHash":"ghi789",
"policySetName":"Configurations",
"policySetDescription":""
},
"accessType":"read",
"accessDescription":null,
"metaData":"{\"Name\":\"ServiceName\"}"
}
]
}
]
}
]
所以我基本上有一个用户有 x 数量的 ResourceTypesUserVms 并且这些 ResourceTypes 有 x ResourceUserVms。
我需要过滤 ResourceUserVms 内的属性“metaData”。因此,例如,如果在过滤器栏中输入“Admin”,我希望得到这样的回报:
[
{
"userName":"John",
"resourceTypeUserVms":[
{
"name":"Administration",
"description":null,
"resourceUserVms":[
{
"policyUserVm":{
"policyName":"admin",
"priority":0,
"metaHash":"abc123",
"policySetName":"Admin",
"policySetDescription":""
},
"accessType":"Administration",
"accessDescription":null,
"metaData":"{\"Name\":\"Admin\"}"
}
]
}
]
}
]
我在网上找到了一些解决方案,建议我这样做:
filteredUsers = users
.Where(x => x.ResourceTypeUserVms
.Any(x => x.ResourceUserVms
.Any(x => x.MetaData.ToLower().Contains(value))))
.ToList();
但是,这不会产生我想要的结果。
我通过这样做得到了预期的结果(前面的代码不干净):
foreach(var user in users)
{
foreach(var resourceType in user.ResourceTypeUserVms)
{
foreach(var resource in resourceType.ResourceUserVms)
{
if (resource.MetaData.ToLower().Contains(value))
{
filteredUsersTemp.Add(
new UserUserVm
{
UserName = user.UserName,
ResourceTypeUserVms = new List<ResourceTypeUserVm>(
new ResourceTypeUserVm[] {
new ResourceTypeUserVm
{
Description = resourceType.Description,
Name = resourceType.Name,
ResourceUserVms = new List<ResourceUserVm>(
new ResourceUserVm[]{ resource }
)
}
})
}
);
}
}
}
}
如果有人能帮我找出一个使用 LINQ 的好方法,我将不胜感激!
【问题讨论】:
-
LINQ 的结果是什么?另外,您是否考虑过设置字典?
-
LINQ 返回正确的用户,但该用户的所有 ResourceTypes 和 Resources 都会返回,而不仅仅是具有过滤值的那个。不,我没有考虑过字典。你认为我可以以什么方式使用它们?
-
为了只返回相关的 ResourceTypes 和 Resources,您需要改变这些列表。 LINQ 的
.Where不会这样做,它会影响根集合中的哪些项目被返回,它不会改变项目本身。您可以使用 LINQ 的.Select()返回与原始项目不同的内容,但为了改变对象,您可能需要 deep clone 它并更改resourceTypeUserVms属性。真正需要的是执行这些任务并在 LINQ 中调用这些方法的单独方法。 -
@Snoopy111 这是因为您拥有的 linq 正在返回具有您的搜索词的用户。如果要指定要返回的数据,则需要在 LINQ 中使用 Select 。字典类似于使用 LINQ,但关键是您要搜索的内容,并且适用于大型数据集。您也可以创建字典字典
标签: c# list linq nested filtering