我有以下DTO:
class Permission
{
public string ObjectId { get; set; }
public string ObjectType { get; set; }
public string Scope { get; set; }
public string? AccountId { get; set; }
public string? GroupId { get; set; }
}
var permissions = new List<Permission>()
{
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = "1", GroupId = null },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = "2", GroupId = null },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = null, GroupId = "1" },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:write", AccountId = "2", GroupId = null },
new(){ ObjectId = "2", ObjectType = "link", Scope = "link:read", AccountId = "1", GroupId = null },
};我希望得到以下结果:
{[
"1": {
"read": {
"accounts": ["1", "2"],
"groups": ["1", "2", "3"]
},
"write": {
"accounts": ["1", "2"],
"groups": ["1", "2", "3"]
}
}
]}基本上是Permission的一个对象数组,按其ObjectId属性分组,然后按每个包含AccountId或GroupId属性数组的Scope进行分组。
每个Permission可以有相同的ObjectId,但是有不同的Scope、AccountId和GroupId。
我尝试使用GroupBy,但这给了我一个IGrouping,我不知道如何继续。
发布于 2022-10-26 08:59:04
您需要的不仅仅是嵌套的组bys。在您的输出JSON中,您有键作为属性名。您还需要使用ToDictionary将值转换为属性键。
var permissions = new List<Permission>()
{
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = "1", GroupId = null },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = "2", GroupId = null },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:read", AccountId = null, GroupId = "1" },
new(){ ObjectId = "1", ObjectType = "link", Scope = "link:write", AccountId = "2", GroupId = null },
new(){ ObjectId = "2", ObjectType = "link", Scope = "link:read", AccountId = "1", GroupId = null },
};
var result = permissions.GroupBy(r=> r.ObjectId).Select(r=> new {
r.Key,
InnerGroups = r.GroupBy(q=> q.Scope.Replace("link:","")).Select(q=> new {
Scope = q.Key,
Accounts = q.Where(z=> z.AccountId != null).Select(z=> z.AccountId).ToArray(),
Groups = q.Where(z=> z.GroupId != null).Select(z=> z.GroupId).ToArray()
})
})
.ToDictionary(r=> r.Key,r=> r.InnerGroups.ToDictionary(q=> q.Scope,q=> new {q.Accounts,q.Groups}));
var serialized = JsonSerializer.Serialize(result,new JsonSerializerOptions{ WriteIndented=true });这是输出:
{
"1": {
"read": {
"Accounts": [
"1",
"2"
],
"Groups": [
"1"
]
},
"write": {
"Accounts": [
"2"
],
"Groups": []
}
},
"2": {
"read": {
"Accounts": [
"1"
],
"Groups": []
}
}
}发布于 2022-10-26 09:00:55
您必须使用嵌套的GroupBy来实现这一点,然后将结果转换为字典:
var result = permissions
.GroupBy(p => p.ObjectId)
.ToDictionary(g => g.Key, g => g.GroupBy(g => g.Scope)
.ToDictionary(g => g.Key, g => new
{
accounts = g.Select(per => per.AccountId).Distinct().ToList(),
groups = g.Select(per => per.GroupId).Distinct().ToList()
}));https://stackoverflow.com/questions/74204742
复制相似问题