System.Linq.Dynamic.Core - 查询嵌套对象

时间:2021-07-26 16:02:20

标签: c# vb.net linq lambda dynamic

我有一个 JSON 文件,我将其反序列化为一个对象,该对象在基本结构级别具有以下内容:

--- 网站

------ 网站产品

-----------产品名称

-----------数量

----------价格

----------等。等

我需要/希望能够动态查询此结构(Site/SiteProducts 只是我需要查询的许多类似对象的一个​​示例),并且一直在尝试让动态 LINQ 工作。

此 LINQ 语句为我提供了与给定产品匹配的数量总和的输出:

json.Sites.Select(Function(s) s.SiteProducts.Where(Function(sp) sp.ProductName = "Widget").Select(Function(spd) spd.Quantity).Sum)

但是,我无法弄清楚相应的动态LINQ。我认为这可能有效:

jsonObj.Select("new (Sites.Select(SiteProducts).Where(it.ProductName=""Widget"").Select(Quantity).Count())")

但不是,因为 siteproducts 不包含 ProductName。

这甚至可以用动态 LINQ 实现吗?我看过动态 lambda 表达式,但它们看起来很复杂。我想我只需要知道我是否遗漏了一些明显的东西(比如在我的动态选择/where 中轻松拥有一个 lambda 函数的能力)或者这是不可能的?

谢谢:-)

2 个答案:

答案 0 :(得分:0)

由于不清楚您是要动态反序列化还是要反序列化到已知的类,这里有几个例子

  1. 从类创建一个 json 字符串
  2. 反序列化为类
  3. 反序列化为 JObject
void Main()
{
    var root = new ROOT(){
        Price= 22.33M,
        Quantity = 2,
        ProductName = "Test",
        SiteProducts = { "Prod 1", "Prod 2" },
        Sites = new List<Site>() { new Site() {Name = "Test Site", URL = "http://google.com"}}
    };
    var JSONstr = JsonConvert.SerializeObject(root).Dump();
    //deserialize to ROOT class
    var JObjclass = JsonConvert.DeserializeObject<ROOT>(JSONstr).Dump("ROOT CLASS");
    //deserialize to anonimus JObject
    var JObj = JsonConvert.DeserializeObject<JObject>(JSONstr).Dump();
    
    JObj["Sites"][0]["Name"].ToString().Dump("");
    
    
}

public class ROOT
{
    public List<Site> Sites { get; set; }

    public List<string> SiteProducts { get; set; }

    public string ProductName { get; set; }

    public int Quantity { get; set; }

    public decimal Price { get; set; }
    public ROOT()
    {
        Sites = new List<Site>();
        SiteProducts = new List<string>();
        Quantity = 0;
        Price = 0;
    }

}
public class Site
{
    public string Name { get; set; }
    public string URL { get; set; }

}
{
  "Sites": [
    {
      "Name": "Test Site",
      "URL": "http://google.com"
    }
  ],
  "SiteProducts": [
    "Prod 1",
    "Prod 2"
  ],
  "ProductName": "Test",
  "Quantity": 2,
  "Price": 22.33
}

enter image description here

答案 1 :(得分:0)

最后,我最终使用了一个从注释之一指向 Newtonsoft 库中 JObject 对象的指针,并发现了使用 JSONPath 动态查询对象的能力。这解决了我的问题(没有动态 Linq 库,据我所知,它不允许您查询嵌套数组对象)。

点击此处了解更多信息:https://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenJsonPath.htm

还有一个可行的例子:

jObj.SelectToken("$.Sites[*].SiteProducts[?(@.ProductName == 'Widget')].Quantity")

感谢指导:)