c# - Using Linq to select into an object with children from Json -
i'm novice c# dev , newer linq, i'm trying figure out how nested child objects linq query object. can main/root objects.
this code far , json file i'm using. note, manually removed text json if happens appear malformed.
class program { static void main(string[] args) { program p = new program(); p.processjson(); console.readline(); } public void processjson() { jobject jobject = jobject.parse(this.getsampleorderjsontext()); // question in block of code var orders = p in jobject["resource"]["items"].children()["resource"] select new orderheader { orderno = (string)p["orderno"], status = (string)p["status"] // how fill "lines" , child object "lines.linedetails"? // lines = }; foreach (orderheader orderlist in orders) { console.writeline(orderlist.orderno + " " + orderlist.status); } } public class orderheader { public string orderno { get; set; } public string status { get; set; } public list<orderline> lines { get; set; } } public class orderline { public string sku { get; set; } public int quantity { get; set; } public list<orderlinedetail> linedetails { get; set; } } public class orderlinedetail { public int productid { get; set; } public string serialnumber { get; set; } } public string getsampleorderjsontext() { return "{entire json text}"; // returns jsontext } } here (edited) json:
{ "status": 200, "message": "successful", "resource": { "offset": 0, "total": 1, "previous": null, "next": null, "items": [{ "resource": { "orderno": "#6255.1", "lastupdateddate": "2016-01-21t17:39:36-08:00", "status": "completed", "vendorid": null, "vendorexternalid": null, "id": 153357642, "items": { "resource": { "offset": 0, "total": 3, "previous": null, "next": null, "items": [{ "resource": { "sku": "796430390315", "quantity": 2, "serialnumbers": { "resourcelocation": null, "resource": { "offset": 0, "total": 2, "previous": null, "next": null, "items": [{ "resourcelocation": null, "resource": { "orderid": 153357642, "productid": 3525462, "serialnumber": "t8-0139062" } }, { "resourcelocation": null, "resource": { "orderid": 153357642, "productid": 3525462, "serialnumber": "t8-0139063" } }] } }, "productid": 3525462, "orderid": 153357642, "ordered": 2, "shipped": 1 } }, { "resource": { "sku": "796430390322", "quantity": 2, "commercialinvoicevalue": 0, "serialnumbers": { "resourcelocation": null, "resource": { "offset": 0, "total": 2, "previous": null, "next": null, "items": [{ "resourcelocation": null, "resource": { "orderid": 153357642, "productid": 3525472, "serialnumber": "t8-0140454" } }, { "resourcelocation": null, "resource": { "orderid": 153357642, "productid": 3525472, "serialnumber": "t8-0140478" } }] } }, "productid": 3525472, "orderid": 153357642, "ordered": 2, "shipped": 1 } }, { "resourcelocation": null, "resource": { "sku": "796430390346", "quantity": 1, "commercialinvoicevalue": 0, "serialnumbers": { "resourcelocation": null, "resource": { "offset": 0, "total": 1, "previous": null, "next": null, "items": [{ "resourcelocation": null, "resource": { "orderid": 153357642, "productid": 3525482, "serialnumber": "t8-0141520" } }] } }, "productid": 3525482, "orderid": 153357642, "ordered": 1, "shipped": 1 } }] } } "options": { "resourcelocation": null, "resource": { "warehouseid": 13, "warehouseregion": "chi", "carriercode": "fdx" } } "shipto": { "resource": { "email": "none@nowhere.com", "name": "first last", "company": "company, inc", "address1": "123 south street", "address2": "", "address3": "", "city": "chicago", "state": "il", "postalcode": "60652", "country": "us", "phone": "5555551234" } } "pricing": { "resourcelocation": null, "resource": { "shipping": 20.76, "packaging": 0.88, "insurance": 9, "handling": 5.25, "total": 35.89 } } } }] } } edit: working code! best way it? if child-element doesn't exist?
public void processjson() { jobject jobject = jobject.parse(this.getsampleorderjsontext()); var orders = p in jobject["resource"]["items"].children()["resource"] select new orderheader { orderno = (string)p["orderno"], status = (string)p["status"], lines = ( nestedchildren in p["items"]["resource"]["items"].children()["resource"] select new orderline { sku = (string)nestedchildren["sku"], quantity = (int)nestedchildren["quantity"] }) }; foreach (orderheader orderlist in orders) { console.writeline(orderlist.orderno + " " + orderlist.status); if (orderlist.lines != null) { foreach (orderline line in orderlist.lines.tolist()) { console.writeline("-->{0}: {1}", line.sku, line.quantity); } } } }
the question if there better way write query borders philosophical. ways differently though? yes, , lots of it!
the select/from syntax of linq heavily inspired sql of course , declarative paradigm has number of advantages , disadvantages instance compared purely imperative c-like query.
sql-style linq:
- fewer instructional overhead (you don't care datatype definitions , procedure)
- they can provide more straight-forward on data queried
- especially query nesting can lead horrific , inefficient statements computationally complex
extension method linq:
something like:
var myquery = mydatastructure.where( data => data.property == mysearchproperty ) .distinct() .select( data => data.customerid ); - integrates more , unobstrusively c-style method
- superbly suited quick statements produce overhead if written in c-style
- can wildy inefficient if done wrong
c-style query:
- typically consists of number of nested loops
- provides control on how data queried
- quickly produces lot of overhead variable , structural definitions
- can lot more efficient if want add instructions during query
- can extremely efficient if know better compiler how parallelize (for instance parallel.foreach)
- usually less easy read desired data pattern hidden deeper in structure opposed sql-like query
annother method has becomely popular in cloud big data , high parallization no-sql syntax; topic own.
for specific case have admit, don't understand how data structured -
p["items"]["resource"]["items"].children()["resource"] confuses me , seems rather unusual. long data want , code readable , maintainable can't go wrong here. unless have specific conditions huge amounts of data or time concerns query seems fine me.
Comments
Post a Comment