如何过滤 json 联接中的布尔字段

How to filter a Boolean field in a json join

抱歉这么快就回来了。我尝试了很多方法,但我无法编译代码,因为我尝试过的一切都告诉我,我不能用布尔字段来做到这一点。我搜索过的每个例子都给出了 ? x == 1。但我正在尝试筛选具有布尔值的字段? x == 真。

我试过在 foreach 循环中进行过滤,更改为 for 循环,向 where 添加条件,也向 join 和 RemoveAll 添加条件。我无法 find/think 尝试任何其他方法。缺乏经验让我丧命。

我需要过滤 catObj。["IncludeCategory"] == true。

感谢任何帮助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class TestClass
{
  public static void Test()
  {
    // Load categories.json
    JObject catObj = JObject.Load(new JsonTextReader(File.OpenText("D:/Code/Tests/categories.json")));
    // Load techtypes.json
    JObject ttObj = JObject.Load(new JsonTextReader(File.OpenText("D:/Code/Tests/techtypes.json")));

    foreach (var categoriesJson in catObj)
        //foreach (var categoriesJson in GetCategoriesJson())
        foreach (var itemsJson in ttObj)
      {
        // Filter variables
        var gameVersions = new HashSet<string> { "A", "2" };
        var categoryIDs = new HashSet<string> { "outcrop" };

        // Left outer join on ttObj.  Select all Items[*] array items
        var query = from i in ttObj.SelectTokens("TechType[*]").OfType<JObject>()
                      // Filter on the game version and category ID
                    let categoryId = (string)i["CategoryID"]
                    let gameVersion = (string)i["GameVersion"]
                    where
                    categoryIDs.Count() > 0 ? 
                      categoryIDs.Contains(categoryId) && gameVersions.Contains(gameVersion) && gameVersions.Contains(gameVersion)  : gameVersions.Contains(gameVersion) && gameVersions.Contains(gameVersion)

                    // Join with "Categories[*]" on category ID
                    join c in catObj.SelectTokens("Categories[*]") on categoryId equals (string)c["CategoryID"] into joined
                    // DefaultIfEmpty makes this a left join
                    from cat in joined.DefaultIfEmpty()
                      // Select all records of i and add the CategoryDescription from cat.
                    select new JObject(i.Properties()) { new JProperty("CategoryDescription", cat?["CategoryDescription"]) };

        var results = query.ToList(); // Materialize the query into a list of results.

        Console.WriteLine(JsonConvert.SerializeObject(results, Formatting.Indented));

        Console.WriteLine();
      }
  }

  public class TechType
  {
    public string CategoryID { get; set; }
    public string TechName { get; set; }
    public string SpawnID { get; set; }
    public int TechID { get; set; }
    public string GameVersion { get; set; }
  }

  public class TechTypeRoot
  {
    public List<TechType> TechType { get; set; }
  }

  public class Categories
  {
    public string CategoryID { get; set; }
    public string CategoryDescription { get; set; }
    public bool IncludeCategory { get; set; }
    public string GameVersion { get; set; }
  }

  public class CategoriesRoot
  {
    public List<Categories> Categories { get; set; }
  }
}

public class Program
{
  public static void Main()
  {
    try
    {
      TestClass.Test();
    }
    catch (Exception ex)
    {
      Console.WriteLine("Failed with unhandled exception: ");
      Console.WriteLine(ex);
      throw;
    }
  }
}

catObj json

{
  "Categories": [
    {
      "CategoryID": "baseupgrades",
      "CategoryDescription": "Base Upgrades",
      "IncludeCategory": true,
      "GameVersion": "A"
    },
    {
      "CategoryID": "batteries",
      "CategoryDescription": "Batteries",
      "IncludeCategory": true,
      "GameVersion": "A"
    },
    {
      "CategoryID": "blueprint",
      "CategoryDescription": "Blueprint",
      "IncludeCategory": false,
      "GameVersion": "A"
    },

ttObj json

{
  "TechType": [
    {
      "CategoryID": "crystalline",
      "TechName": "Quartz",
      "SpawnID": "quartz",
      "TechID": 1,
      "GameVersion": "A"
    },
    {
      "CategoryID": "metals",
      "TechName": "Metal Salvage",
      "SpawnID": "scrapmetal",
      "TechID": 2,
      "GameVersion": "A"
    },
    {
      "CategoryID": "outcrop",
      "TechName": "Limestone Outcrop",
      "SpawnID": "limestonechunk",
      "TechID": 4,
      "GameVersion": "A"
    },

好的,我不得不将连接更改为右连接,如我在第一个 post 中所述。现在我可以访问 where 子句中的所有字段了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class TestClass
{
    public static void Test()
    {
        // Load categories.json
        JObject catObj = JObject.Load(new JsonTextReader(File.OpenText("D:/Code/Tests/categories.json")));
        // Load techtypes.json
        JObject ttObj = JObject.Load(new JsonTextReader(File.OpenText("D:/Code/Tests/techtypes.json")));

        foreach (var categoriesJson in catObj)
        {
            // Filter variables
            var gameVersions = new HashSet<string> { "A", "1" };
            var categoryIDs = new HashSet<string> { "metals", "tablets" };
            var usedInMod = new HashSet<bool> { true };

            // Right outer join on catObj.  Select all Items[*] array items
            var query = from c in catObj.SelectTokens("Categories[*]").OfType<JObject>()
                                    let categoryId = (string)c["CategoryID"]

                                    // Join catObj with ttObj on CategoryID
                                    join t in ttObj.SelectTokens("TechType[*]") on categoryId equals (string)t["CategoryID"]
                                    let gameVersionC = (string)c["GameVersion"]
                                    let gameVersionT = (string)t["GameVersion"]
                                    // Process the filters
                                    where categoryIDs.Count() > 0 ?
                                    usedInMod.Contains((bool)c["UsedInMod"]) && gameVersions.Contains(gameVersionC) && gameVersions.Contains(gameVersionT) && categoryIDs.Contains(categoryId) :
                                    usedInMod.Contains((bool)c["UsedInMod"]) && gameVersions.Contains(gameVersionC) && gameVersions.Contains(gameVersionT)

                                    select new
                                    {
                                        CategoryDescription = c["CategoryDescription"],
                                        CategoryID = c["CategoryID"],
                                        TechName = t["TechName"],
                                        SpawnID = t["SpawnID"],
                                        TechID = t["TechID"],
                                        GameVersion = t["GameVersion"]
                                    };

            var results = query.ToList(); // Materialize the query into a list of results.

            Console.WriteLine(JsonConvert.SerializeObject(results, Formatting.Indented));

            Console.WriteLine();
        }
    }
}

public class Program
{
    public static void Main()
    {
        try
        {
            TestClass.Test();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Failed with unhandled exception: ");
            Console.WriteLine(ex);
            throw;
        }
    }
}