2012-09-17 41 views
8

我有一个从API调用接收到的Json响应。它有几个嵌套级别,如下所示(这是一个片段):使用LINQ查询JSON

"Items": [ 
    { 
    "Result": { 
     "Id": "191e24b8-887d-e111-96ec-000c29128cee", 
     "Name": "Name", 
     "StartDate": "2012-04-03T00:00:00+01:00", 
     "EndDate": null, 
     "Status": { 
     "Name": "Active", 
     "Value": 5 
     }, 
     "Client": { 
     "Id": "35ea10da-b8d5-4ef8-bf23-c829ae90fe60", 
     "Name": "client Name", 
     "AdditionalItems": {} 
     }, 
     "ServiceAgreement": { 
     "Id": "65216699-a409-44b0-8294-0e995eb05d9d", 
     "Name": "Name", 
     "AdditionalItems": { 
      "ScheduleBased": true, 
      "PayFrequency": { 
      "Id": "981acb72-8291-de11-98fa-005056c00008", 
      "Name": "Weekly", 
      "AdditionalItems": {} 
      }, 
      "PayCycle": [ 
      { 
       "Name": "Schedule Based", 
       "ScheduleBased": true, 
       "SelfBilling": false, 
       "Id": "a8a2ecc4-ff79-46da-a135-743b57808ec3", 
       "CreatedOn": "2011-09-16T23:32:19+01:00", 
       "CreatedBy": "System Administrator", 
       "ModifiedOn": "2011-09-16T23:32:19+01:00", 
       "ModifiedBy": "System Administrator", 
       "Archived": false 
      } 
      ] 
     } 
     }, 
} 
] 
... 

我想要做的就是从retreive使用LINQ的PayCycle节点的数据。我可以在例如控制器使用下面的LINQ得到使用真实Result.ServiceAgreement.AdditionalItems.SchedultedBased的值项:

var result = from p in data["Data"]["Items"].Children() 
      where (bool)p["Result"]["ServiceAgreement"]["AdditionalItems"]["ScheduleBased"] == true 
      select new 
      { 
       Name = (string)p["Result"]["Client"]["Name"], 
       Id = (string)p["Result"]["Client"]["Id"] 
      }; 

现在我需要得到Result.ServiceAgreement.AdditionalItems.Paycycle.ScheduleBasedSelfBilling性能。我如何做到这一点,如果PayCycle也是一个数组,我如何获得孩子,就像我在上面的Linq中使用Data.Items一样,这样我就可以在这两个项目上使用where子句过滤器?

回答

12

可以反序列化JSON成dynamic对象,然后使用LINQ对象:

[TestMethod] 
    public void TestMethod1() 
    { 
     const string json = @"""Items"": [ 
{ 
""Result"": { 
    ""Id"": ""191e24b8-887d-e111-96ec-000c29128cee"", 
    ""Name"": ""Name"", 
    ""StartDate"": ""2012-04-03T00:00:00+01:00"", 
    ""EndDate"": null, 
    ""Status"": { 
    ""Name"": ""Active"", 
    ""Value"": 5 
    }, 
    ""Client"": { 
    ""Id"": ""35ea10da-b8d5-4ef8-bf23-c829ae90fe60"", 
    ""Name"": ""client Name"", 
    ""AdditionalItems"": {} 
    }, 
    ""ServiceAgreement"": { 
    ""Id"": ""65216699-a409-44b0-8294-0e995eb05d9d"", 
    ""Name"": ""Name"", 
    ""AdditionalItems"": { 
     ""ScheduleBased"": true, 
     ""PayFrequency"": { 
     ""Id"": ""981acb72-8291-de11-98fa-005056c00008"", 
     ""Name"": ""Weekly"", 
     ""AdditionalItems"": {} 
     }, 
     ""PayCycle"": [ 
     { 
      ""Name"": ""Schedule Based"", 
      ""ScheduleBased"": true, 
      ""SelfBilling"": false, 
      ""Id"": ""a8a2ecc4-ff79-46da-a135-743b57808ec3"", 
      ""CreatedOn"": ""2011-09-16T23:32:19+01:00"", 
      ""CreatedBy"": ""System Administrator"", 
      ""ModifiedOn"": ""2011-09-16T23:32:19+01:00"", 
      ""ModifiedBy"": ""System Administrator"", 
      ""Archived"": false 
     } 
     ] 
    } 
    } 
} 
} 
]"; 
     dynamic data = System.Web.Helpers.Json.Decode("{" + json + "}"); 

     var result = from i in (IEnumerable<dynamic>)data.Items 
        where i.Result.ServiceAgreement.AdditionalItems.ScheduleBased == true 
        select new 
          { 
           i.Result.Client.Name, 
           i.Result.Client.Id 
          }; 

     Assert.AreEqual(1, result.Count()); 
     Assert.AreEqual("client Name", result.First().Name); 
     Assert.AreEqual("35ea10da-b8d5-4ef8-bf23-c829ae90fe60", result.First().Id); 
    } 

注意,我不得不加上括号{和}包围你的例子JSON字符串,否则.NET json解析器不喜欢它。

+0

我已经稍微修改了我的PayCycle集合,只返回集合中的1个项目。例如,我为了获得SelfBilling属性,我在where子句中完成了以下内容:where(bool)p [“Result”] [“ServiceAgreement”] [“AdditionalItems”] [“PayCycle”] [0] [“SelfBilling”] == false。这给了我正在寻找的结果。 – KDee

0

首先,我不熟悉使用这种格式编写LINQ/LAMBDA [“some”] [“thing”]。 我的第一步是创建一些类/对象来存放数据,以便随后创建任何代码。

例如

public class Result 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; }, 
    public DateTime StartDate { get; set; } 
    //you get the idea 
} 

但可能试试以下?

var result = from p in data["Data"]["Items"].Children() 
       where (bool)p["Result"]["ServiceAgreement"]["AdditionalItems"]["ScheduleBased"] == true 
        && (p["Result"]["ServiceAgreement"]["AdditionalItems"]["PayCycle"]).Where(o => o.["ScheduleBased"] == true) 
       select new 
       { 
        Name = (string)p["Result"]["Client"]["Name"], 
        Id = (string)p["Result"]["Client"]["Id"] 
       };