【问题标题】:LINQ to JSON - Querying an arrayLINQ to JSON - 查询数组
【发布时间】:2016-03-31 14:27:43
【问题描述】:

我需要选择 json 数组中包含“3”的用户。

{
    "People":[  
    {  
        "id" : "123",
        "firstName" : "Bill",
        "lastName" : "Gates",
        "roleIds" : {
                "int" : ["3", "9", "1"]
            }
    },
    {  
        "id" : "456",
        "firstName" : "Steve",
        "lastName" : "Jobs",
        "roleIds" : {
            "int" : ["3", "1"]
        }
    },
    {  
        "id" : "789",
        "firstName" : "Elon",
        "lastName" : "Musk",
        "roleIds" : {
            "int" : ["3", "7"]
        }
    },
    {
        "id" : "012",
        "firstName" : "Agatha",
        "lastName" : "Christie",
        "roleIds" : {
            "int" : "2"
        }
    }
]}

最后,我的结果应该是 Elon Musk 和 Steve Jobs。这是我使用的代码(以及其他变体):

var roleIds = pplFeed["People"]["roleIds"].Children()["int"].Values<string>();


var resAnAssocInfo = pplFeed["People"]
.Where(p => p["roleIds"].Children()["int"].Values<string>().Contains("3"))
.Select(p => new
{
    id = p["id"],
    FName = p["firstName"],
    LName = p["lastName"]
}).ToList();

我收到以下错误:

"Accessed JArray values with invalid key value: "roleIds".  Int32 array index expected"

我将 .Values&lt;string&gt;() 更改为 .Values&lt;int&gt;() 仍然没有运气。

我做错了什么?

【问题讨论】:

  • 您的 JSON 无效。上传到jsonformatter.curiousconcept.com查看问题。可能 {"People": [{ { "id" : "123" ... 应该是 {"People": [{ "id" : "123" ... ,匹配的 } 也从末尾删除?
  • 好眼光。我已经更新了 json 以遵循正确的格式。但是,它仍然不起作用。知道我做错了什么吗?

标签: linq json.net linq-to-json


【解决方案1】:

你很接近。从此更改您的 Where 子句:

.Where(p => p["roleIds"].Children()["int"].Values<string>().Contains("3"))

到这里:

.Where(p => p["roleIds"]["int"].Children().Contains("3"))

你会得到你想要的结果(尽管在你的示例数据中实际上有三个用户的角色 ID 为"3",而不是两个)。

但是,您可能会遇到另一个问题,但此代码仍然无法解决。您会注意到,对于 Agatha Christie,int 的值不像其他数组,它是一个简单的字符串。如果该值有时是一个数组,有时不是,那么您需要一个可以处理两者的 where 子句。像这样的东西应该可以工作:

.Where(p => p["roleIds"]["int"].Children().Contains(roleId) ||
            p["roleIds"]["int"].ToString() == roleId)

...其中roleId 是一个包含您要查找的ID 的字符串。

小提琴:https://dotnetfiddle.net/Zr1b6R

【讨论】:

    【解决方案2】:

    问题在于并非所有对象都遵循相同的接口。该列表中的最后一项在 roleIds.int 属性中具有单个字符串值,而所有其他项都有一个数组。您需要规范化该属性,然后进行检查。如果它们都是数组,那将是最简单的。

    你应该可以这样做:

    var roleId = "3";
    var query =
        from p in pplFeed["People"]
        let roleIds = p.SelectToken("roleIds.int")
        let normalized = roleIds.Type == JTokenType.Array ? roleIds : new JArray(roleIds)
        where normalized.Values().Contains(roleId)
        select new
        {
            id = p["id"],
            FName = p["firstName"],
            LName = p["lastName"],
        };
    

    【讨论】:

      猜你喜欢
      • 2020-01-04
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      相关资源
      最近更新 更多