【发布时间】:2020-11-25 10:20:38
【问题描述】:
我想查询 dynamic-key 嵌套字典结构中的值,以便使用 LINQ to SQL 应用权限过滤器(最好使用索引查询而不引起扫描)。
我拥有的 JSON 结构包含一个 Permissions 属性,它基本上只是一个 C# dictionary<string, dictionary<string, dictionary<string, string>>>
JSON 示例:
{
"Permissions": {
"Account 1 GUID": {
"Location": "Location1 GUID"
},
"Account 2 GUID: {
"Location": "Location 2 GUID"
},
"Account 3 GUID": {
"Location": "Location 3 GUID"
}
}
}
帐户密钥属性是动态的,这意味着它们实际上是拥有嵌套位置的帐户的 GUID。
当执行查询时,我有一个位置和帐户 ID 的列表,这些位置和帐户 ID 应该用于通过仅授予对这些位置的访问权限来执行权限过滤。
我要应用的过滤查询是 类似于某事 像这样(这就是我想要实现的目标):
var allowedLocations = new List<string> { "Location 1 GUID", "Location 2 GUID" };
var result = AllDocsIQueryable.Where(model =>
model.Permissions.Values.Where(secondLevel =>
secondLevel.Values.Where(thirdLevel =>
allowedLocations.Contains(thirdLevel)))).ToList();
如您所见,我想通过在我的访问列表中查询包含任何位置 ID 的文档,将用户可以看到的文档过滤为用户定义了访问权限的文档。
我不知道如何构建查询来查询这样的结构。我尝试了很多 .Select 和 .SelectMany 查询的组合,但我尝试过的都没有成功,我尝试过的所有方法都没有结果或失败。
like 的查询会产生正确的结果,但我真的很想避免使用谓词生成器动态构建此查询,例如:
var result = AllDocsIQueryable.Where(model =>
(model.Permissions["Account 1 GUID"]["Location"].IsDefined() &&
model.Permissions["Account 1 GUID"]["Location"] == "Location 1 GUID")
||
(model.Permissions["Account 2 GUID"]["Location"].IsDefined() &&
model.Permissions["Account 2 GUID"]["Location"] == "Location 2 GUID")
// .. etc ..
).ToList();
我希望我的问题很清楚,并且有一个 LINQ to SQL/Cosmos/NoSQL/C# 超级向导可以帮助我构建这个查询?也许有人知道我根本无法构造这个查询,我需要更改 JSON 结构(我知道这会更好)?我需要使用 LINQ 而不是 SQL 查询字符串进行查询!
结论:
正如我所担心的那样,似乎无法构建查询。
据我所知,并且已经尝试和阅读,如果不将动态帐户密钥构建到查询中,就没有办法做到这一点。
我已更改架构以包含数组。
"Permissions": [
{
"LocationId": "Loc1",
"AccountId": "Acc1"
},
{
"LocationId": "Loc2",
"AccountId": "Acc2"
}
]
【问题讨论】:
-
您的问题不清楚。您提供的 LINQ 查询甚至没有编译,那么您为什么声称它没有产生任何结果?为什么您仅针对“帐户 1 GUID”检查“位置 1 GUID”而仅针对“帐户 2 GUID”检查“位置 2 GUID”?请完全准确地说明您要达到的目标。另外,请说明您是否必须使用 LINQ,或者您是否还可以构造 SQL 查询字符串。
-
@MoB。我已经编辑并试图澄清这个问题。 1) 我要应用的过滤查询类似于这样: 2) 我需要使用 LINQ 进行查询,而不是SQL 查询字符串! 3) 我知道位置 ID 所在的帐户 ID。我不明白您的问题?我想只过滤允许列表中的任何位置命中,正如您在示例查询中看到的那样,我希望 LIKE 能够使用!我认为我实际上对我想要实现的目标非常精确,但我已经大胆地说明了我需要什么!
-
抱歉,目前还不清楚。您的 LINQ 查询没有任何意义。所以基本上你忽略了帐户 ID,只是想检查文档的权限对象中是否包含任何给定的位置 ID 集?
-
可以更改文档结构吗?然后您可以将帐户ID存储在属性“accountId”中,权限将是一个数组,查询将非常简单。
-
@MoB。对,就是这样!这就是我想要实现的!在第二个查询中,我说明了如何使用帐户 ID GUID,我可以实现产生正确结果的查询。但是,我注意到我不想那样做,因为我需要动态构建(相当大的)查询,对吧?
标签: c# json .net linq-to-sql azure-cosmosdb