使用嵌套数组的LINQ到JSON查询的正确语法



我有一个Json"数据库",正在尝试使用Newtonsoft Json.Net LINQ从中提取内容。

目标是从包含在父数组项中的子数组项中提取属性。父数组中的项将由键属性选择。"outer"元素是一个包含一个条目的数组,"internal"元素是由两个父条目组成的数组,每个父条目都有一个"key"和一个子"items"数组。希望通过其key匹配内部父条目,然后将子数组中所有项的子"itemid"属性提取到IList中。

file at filePath contains:
{
   "outer":
   [
      {
         "inner":
         [
            {
               "key": "AAA",
               "items":
               [
                  { "itemid": "a1" }
               ]
            },
            {
               "key": "BBB",
               "items":
               [
                  { "itemid": "b1" },
                  { "itemid": "b2" }
               ]
            }
         ]
      }
   ]
}

我认为提取查询看起来像下面所示,但无论是这个还是我尝试过的几十个变体都没有成功。在一些变体中,它似乎一直工作到最终选择正确的内部"项目",但当我试图挖掘出"项目ID"数组时,它就崩溃了有什么线索吗?如果需要的话,我愿意把它分成两个单独的查询。

public IList<string> FindMatchingItems(string filePath, string id)
{
    JObject JsonLinq = JObject.Parse(File.ReadAllText(filePath));
    return JsonLinq["outer"].First()["inner"].Children()
        .First(inner => inner["key"].ToString() == id)
        .Select(selected => selected["items"].Children()["itemid"].ToString())
        .ToList();
}
void Query(string filePath)
{
    var ayes = FindMatchingItems(filePath, "AAA");
    // ayes contains [] { "a1" }
    var bees = FindMatchingItems(filePath, "BBB");
    // bees contains [] { "b1", "b2" }
}

我想这就是您想要的:

JsonLinq["outer"].First()["inner"]
    .Where(innerItem => innerItem["key"].Value<string>() == id)
    .SelectMany(innerItem => innerItem["items"]
        .Select(itm => itm["itemid"].Value<string>()))
    .ToList();

这里的关键是使用.SelectMany将投影的itemid展平为一个新列表。

您可以在C#中创建一个类,然后使用JsonConvert.DescializeObject()

C# class
public class Item
{
    public string itemid { get; set; }
}
public class Inner
{
    public string key { get; set; }
    public List<Item> items { get; set; }
}
public class Outer
{
public List<Inner> inner { get; set; }
}
public class RootObject
{
    public List<Outer> outer { get; set; }
 }

然后你可以使用

    public List<string> FindMatchingItems(string filePath, string id)
    {
        var json = File.ReadAllText(filePath);
        var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
        var result = rootObject.outer.First().inner.First(i => i.key == id).items.Select(item => item.itemid).ToList();
        return result;
    }

相关内容

  • 没有找到相关文章

最新更新