LINQ到JSON-查询数组

LINQ到JSON-查询数组,linq,json.net,linq-to-json,Linq,Json.net,Linq To Json,我需要选择json数组中有“3”的用户 { "People":[ { "id" : "123", "firstName" : "Bill", "lastName" : "Gates", "roleIds" : { "int" : ["3", "9", "1"] } }, { "id" : "456",

我需要选择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"
        }
    }
]}
最后,我的结果应该是埃隆·马斯克和史蒂夫·乔布斯。这是我使用的代码(&其他变体):

我将
.Values()
更改为
.Values()
,但仍然没有运气


我做错了什么?

你很接近。更改以下内容中的
Where
子句:

.Where(p => p["roleIds"].Children()["int"].Values<string>().Contains("3"))
您将得到所需的结果(尽管示例数据中实际上有三个用户的角色id为
“3”
,而不是两个)

然而,您可能遇到的另一个问题仍然无法解决。您会注意到,对于Agatha Christie,
int
的值与其他数组不同,它是一个简单的字符串。如果该值有时是数组,有时不是数组,那么您需要一个where子句来处理这两者。像这样的方法应该会奏效:

.Where(p => p["roleIds"]["int"].Children().Contains(roleId) ||
            p["roleIds"]["int"].ToString() == roleId)
…其中
roleId
是一个字符串,包含您要查找的id


小提琴手:

你很接近。更改以下内容中的
Where
子句:

.Where(p => p["roleIds"].Children()["int"].Values<string>().Contains("3"))
您将得到所需的结果(尽管示例数据中实际上有三个用户的角色id为
“3”
,而不是两个)

然而,您可能遇到的另一个问题仍然无法解决。您会注意到,对于Agatha Christie,
int
的值与其他数组不同,它是一个简单的字符串。如果该值有时是数组,有时不是数组,那么您需要一个where子句来处理这两者。像这样的方法应该会奏效:

.Where(p => p["roleIds"]["int"].Children().Contains(roleId) ||
            p["roleIds"]["int"].ToString() == roleId)
…其中
roleId
是一个字符串,包含您要查找的id


Fiddle:

问题在于并非所有对象都遵循相同的接口。该列表中的最后一项在
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"],
    };

问题是并非所有对象都遵循相同的接口。该列表中的最后一项在
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"],
    };

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