使用Linq从Json的孩子中选择一个对象 [英] Using Linq to select into an object with children from Json

查看:81
本文介绍了使用Linq从Json的孩子中选择一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#开发人员,还是Linq的新手,但是我试图弄清楚如何将嵌套子对象从Linq查询转换为对象.我可以获取主/根对象.

I'm a novice C# dev and newer to Linq, but I'm trying to figure out how to get the nested child objects from a Linq query into an object. I can get the main/root objects.

到目前为止,这是我的代码以及我正在使用的Json文件.请注意,如果它恰好看起来格式不正确,我会从Json中手动删除一些文本.

This is my code so far and the Json file I'm using. Note, I manually removed some text from the Json if it happens to 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 IS IN THIS BLOCK OF CODE
        var orders =
            from p in jobject["resource"]["items"].Children()["resource"]
            select new orderHeader
            {
                orderNo = (string)p["orderNo"],
                status = (string)p["status"]
                // How do I fill "lines" and its 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}"; // This returns all the JsonText
    }
}

这是我的(编辑后的)杰森:

Here is my (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
                    }
                }
            }
        }]
    }
}


编辑:工作代码!这是最好的方法吗?如果不存在子元素怎么办?


WORKING CODE! Is this the best way to do it? What if a child-element doesn't exist?

public void processJson()
{
    JObject jobject = JObject.Parse(this.getSampleOrderJsonText());

    var orders =
        from p in jobject["resource"]["items"].Children()["resource"]
        select new orderHeader
        {
            orderNo = (string)p["orderNo"],
            status = (string)p["status"],

            lines = (
                from 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 is a better way to write a certain query certainly almost borders the philosophical. Are the ways to do it differently though? Yes, and lots of it!

linq的select/from语法当然受到SQL的极大启发,并且作为声明性范例,与纯粹的命令式C类查询相比,它具有许多优点和缺点.

The select/from syntax of linq is heavily inspired by SQL of course and as a declarative paradigm it has a number of advantages and disadvantages for instance compared to a purely imperative C-like query.

SQl样式的Linq:

  • 更少的教学开销(您不太在乎数据类型定义和过程)
  • 它们可以使查询的数据更加直观
  • 尤其是查询嵌套会导致可怕而低效的语句,因为它们很快会变得计算复杂

扩展方法Linq:

类似的东西:

    var MyQuery = MyDataStructure.Where( data => data.property == mySearchProperty )
                                 .Distinct()
                                 .Select( data => data.CustomerID );

  • 更轻松,更轻松地集成到C风格的方法中
  • 非常适合使用C样式编写时会产生大量开销的快速语句
  • 如果做错了,可能会导致效率低下
  • C风格的查询:

    • 通常由许多嵌套的for循环组成
    • 对如何实际查询数据提供最大的控制权
    • 快速生成用于变量和结构定义的大量开销
    • 如果要在查询过程中添加指令,可以提高效率
    • 如果您比编译器更了解如何并行化它(例如使用Parallel.Foreach),可能会非常高效
    • 通常不易阅读,因为与类似sql的查询相比,所需的数据模式更深地隐藏在结构中

    NO-SQL语法是在云中非常流行的另一种方法,用于处理非常大的数据和很高的并行度.但这是一个主题.

    Annother method that has becomely popular in the cloud for very big data and very high parallization is NO-SQL syntax; however this is a topic for its own.

    我必须承认,对于您的具体情况,我不太了解您的数据的结构-尤其是

    For you specific case I have to admit, I don't really understand how your data is structured - especially

    p["items"]["resource"]["items"].Children()["resource"]
    

    使我感到困惑,并且看起来很不寻常. 但是,只要您获得所需的数据并且代码是可读且可维护的,您在这里就不会真正出错.除非您有大量数据或时间问题之类的特殊条件,否则您的查询对我来说似乎非常好.

    confuses me and seems rather unusual. But as long as you get the data you want and your code is readable and maintainable you can't really go wrong here. Unless you have specific conditions like huge amounts of data or time concerns then your query seems perfectly fine to me.

    这篇关于使用Linq从Json的孩子中选择一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆