1

我需要选择在他们的 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"
        }
    }
]}

最后,我的结果应该是埃隆马斯克和史蒂夫乔布斯。这是我使用的代码(和其他变体):

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<string>().Values<int>(),仍然没有运气。

我究竟做错了什么?

4

2 回答 2

3

你很接近。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)

... whereroleId是一个包含您要查找的 id 的字符串。

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

于 2016-03-31T18:36:46.800 回答
1

问题是并非所有对象都遵循相同的界面。该列表中的最后一项在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"],
    };
于 2016-03-31T18:41:24.940 回答