使用 Linq 选择包含来自 JSON 的子对象的对象

本文关键字:对象 JSON Linq 选择 包含 使用 | 更新日期: 2023-09-27 18:32:20

我是 C# 开发人员新手,也是 Linq 的新手,但我正在尝试弄清楚如何将嵌套的子对象从 Linq 查询获取到对象中。 我可以获取主/根对象。

这是我到目前为止的代码和我正在使用的 Json 文件。请注意,如果 Json 碰巧出现格式不正确,我手动删除了一些文本。

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
    }
}

这是我的(编辑的)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
                    }
                }
            }
        }]
    }
}

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

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

使用 Linq 选择包含来自 JSON 的子对象的对象

是否有更好的方法来编写某个查询的问题当然几乎与哲学接壤。但是,这样做的方法是否不同?是的,而且很多!

当然,linq 的 select/from 语法在很大程度上受到 SQL 的启发,作为一种声明式范式,它有许多优点和缺点,例如与纯粹的命令式 C 类查询相比。

SQl-style Linq:

  • 更少的教学开销(你不太关心数据类型定义和过程)
  • 它们可以更直接地查看所查询的数据
  • 特别是查询嵌套会导致可怕和低效的语句,因为它们很快就会变得计算复杂

扩展方法林克:

像这样:

    var MyQuery = MyDataStructure.Where( data => data.property == mySearchProperty )
                                 .Distinct()
                                 .Select( data => data.CustomerID );
  • 更轻松、更不显眼地集成到 C 型方法中
  • 非常适合快速语句,如果用 C 风格编写会产生很多开销
  • 如果做错了,可能会变得疯狂低效

C 样式查询:

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

在云中流行的另一种用于非常大数据和非常高的Parallization的方法是NO-SQL语法;然而,这是一个自己的主题。

对于您的具体情况,我不得不承认,我真的不了解您的数据是如何构建的 - 尤其是

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

让我感到困惑,似乎很不寻常。但是,只要您获得所需的数据并且您的代码是可读的和维护的,您就不会在这里出错。除非您有特定条件,例如大量数据或时间问题,否则您的查询对我来说似乎完全没问题。