2012-09-17 41 views
8

Tôi có một phản hồi Json mà tôi nhận được từ một cuộc gọi API. Nó có một số cấp lồng nhau như hiển thị bên dưới (đây là một đoạn mã):Truy vấn JSON bằng LINQ

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

Điều tôi muốn làm là truy xuất dữ liệu từ nút PayCycle bằng cách sử dụng LINQ. Tôi có thể ví dụ được các mục với một giá trị true sử dụng Result.ServiceAgreement.AdditionalItems.SchedultedBased sử dụng LINQ sau trong Bộ điều khiển:

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

Bây giờ tôi cần phải nhận được Result.ServiceAgreement.AdditionalItems.Paycycle.ScheduleBasedSelfBilling tài sản. Làm thế nào để làm điều này nếu PayCycle cũng là một mảng, làm thế nào để có được những đứa trẻ như tôi đã làm với Data.Items trong LINQ ở trên để tôi có thể có bộ lọc điều khoản where trên cả hai mục này?

Trả lời

12

Bạn có thể deserialize JSON thành đối tượng dynamic, và sau đó sử dụng LINQ to Objects:

[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); 
    } 

Lưu ý rằng tôi đã có thêm dấu ngoặc {và} xung quanh chuỗi dụ json của bạn, hoặc người nào khác .NET json parser không thích nó.

+0

Tôi đã sửa đổi mỏ một chút khi bộ sưu tập PayCycle sẽ trả lại chỉ 1 mục trong bộ sưu tập. Vì vậy, để tôi có được thuộc tính SelfBilling chẳng hạn, tôi đã làm như sau trong mệnh đề where: where (bool) p ["Result"] ["ServiceAgreement"] ["AdditionalItems"] ["PayCycle"] [0] ["SelfBilling"] == sai. Điều này cho tôi kết quả mà tôi đang tìm kiếm. – KDee

0

Để bắt đầu, tôi không quen với việc viết LINQ/LAMBDA sử dụng định dạng này ["some"] ["thing"]. Bước đầu tiên của tôi là tạo một số lớp/đối tượng để chứa dữ liệu để dễ dàng tạo bất kỳ mã nào sau đó.

ví dụ:

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

Nhưng có thể thử như sau?

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