2016-03-31 14 views
0

json配列に "3"を持つユーザーを選択する必要があります。最後にLINQ to JSON - 配列のクエリ

{ 
    "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<int>().Values<string>()を変更

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

、まだ運:私は次のエラーを取得しています

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(); 

:これは私が使用したコード(&他のバリエーション)です。

私は間違っていますか?

+0

あなたのJSONが無効です。問題を確認するにはhttps://jsonformatter.curiousconcept.com/にアップロードしてください。おそらく '{" People ":[{{" id ":" 123 "...'は '{" People ":{{" id ":" 123 "...'と一致する '}'最後から削除されましたか? – dbc

+0

良い目です。私はjsonを正しいフォーマットに従うように更新しました。しかし、それはまだ動作しません。私が間違っていることは何か考えていますか? –

答えて

2

あなたはかなり近いです。これに

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

:あなたのWhere句は、このから変更

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

と、あなたは、あなたが望む結果を得るでしょう("3"のロールIDを使用して、サンプルデータで3人のユーザーが実際にありますが、 、2つではない)。

しかし、このコードがまだ機能しない場合があるという別の問題があります。 Agatha Christieの場合、intという値は他の配列と同じ配列ではなく、単純な文字列です。値が配列であり、時にはそうでない場合は、両方を扱うことができるwhere節が必要です。このような何か作業をする必要があります:

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

... roleIdは、あなたが探しているIDを含む文字列です。

フィドル:https://dotnetfiddle.net/Zr1b6R

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"], 
    };