如何从字符串数组中在JSON String中创建层次结构



我正在尝试为层次结构生成json字符串:

Company(select * from Company)
    Department(select * from Department)
        Employee(select * from Employee)

上述每个查询将返回以下内容:

Company Fields -  (Id,Name,Location)
Department Fields - (Id,Name,CompanyId)
Employee Fields - (Id,Name,DepartmentId)

现在,我试图为上述实体生成JSON字符串:

预期输出:

{
  "Id": "",
  "Name": "",
  "Location": "",
  "Department": 
        {
           "Id": "",
           "Name": "",
           "CompanyId": "",
           "Employee" : 
               {
                  "Id": "",
                  "Name": "",
                  "DepartmentId": "", 
               }
        }
}

代码:

public string GetData(Child model,List<Parent> parents)
        {
           var fields = new List<string[]>();
           if (parents != null)
           {
                foreach (var parent in parents)
                {
                        var columns = GetColumns(parent); //returns string[] of columns
                        fields.Add(columns);
                 }
            }
            fields.Add(GetColumns(model));
            string json = JsonConvert.SerializeObject(fields.ToDictionary(key => key, v => string.Empty),
                                        Formatting.Indented);
            return json;
        }

现在,当我没有任何父母并且想为只有孩子生成JSON字符串时,代码下方工作正常:

string json = JsonConvert.SerializeObject(fields.ToDictionary(key => key, v => string.Empty),Formatting.Indented)

输出:

{
  "Id": "",
  "Name": "",
  "Location": "",
}

,但现在我想以任何此类内置方式为我的层次结构生成JSON。

我知道我可以循环,附加和创建JSON字符串,但我想像我为孩子所做的那样做得更好。

更新:

public class Child
{
    public string Name { get; set; } // Contains Employee
   //Other properties and info related to process sql query and connection string
}

public class Parent
{
    public string Name { get; set; } // Contains Company,Department.
    public string SqlQuery { get; set; } // query related to Company and Department.
    //Other properties and info related to connection string
}

我创建了一个类,该类在子父母结构中与您提出的信息相似。我还添加了一个自定义的小解析器,可递归起作用。也许这就是您需要的和/或给您解决问题所需的想法的原因。

我还通过添加角度支架(" []")来更改输出。我认为这就是您对多个孩子需要的。至少这就是JSON验证者告诉我我在下面发布的内容。如果您不需要/想要它们,只需在解析器中删除它们。

我认为您无法使用示例中使用的解析器,而没有像我以前的答案中显示的某种形式的额外字段,因为这些解析器通常会以属性名称作为字段,我想您不会想要在运行时动态创建类。

我也不认为您可以创建亲子和孩子的动态深度...与列表,数组或词典的关系,因为这些结构很快就具有设定的深度正如他们被宣布的那样。

类:

public class MyJsonObject
{
    public List<string> Columns = new List<string>();
    public string ChildName;
    public List<MyJsonObject> Children = new List<MyJsonObject>(); 
}

解析器:

class JsonParser
{
    public static string Parse(MyJsonObject jsonObject)
    {
        string parse = "{";
        parse += string.Join(",", jsonObject.Columns.Select(column => $""{column}": """));
        if (!string.IsNullOrEmpty(jsonObject.ChildName))
        {
            parse += $","{jsonObject.ChildName}":";
            parse += $"[{string.Join(",", jsonObject.Children.Select(Parse))}]";
        }
        parse += "}";
        return parse;
    }
}

用法:

class Program
{
    static void Main(string[] args)
    {
        MyJsonObject company = new MyJsonObject();
        company.ChildName = "Department";
        company.Columns.Add("Id");
        company.Columns.Add("Name");
        company.Columns.Add("Location");
        MyJsonObject department = new MyJsonObject();
        department.ChildName = "Employee";
        department.Columns.Add("Id");
        department.Columns.Add("Name");
        department.Columns.Add("CompanyId");
        MyJsonObject employee1 = new MyJsonObject();
        employee1.Columns.Add("Id");
        employee1.Columns.Add("Name");
        employee1.Columns.Add("DepartmentId");
        MyJsonObject employee2 = new MyJsonObject();
        employee2.Columns.Add("Id");
        employee2.Columns.Add("Name");
        employee2.Columns.Add("DepartmentId");
        company.Children.Add(department);
        department.Children.Add(employee1);
        department.Children.Add(employee2);
        var json = JsonParser.Parse(company);
    }
}

输出并链接到JSON-VALIDATOR:

https://jsonformatter.curiousconcept.com/

{  
   "Id":"",
   "Name":"",
   "Location":"",
   "Department":[
      {  
         "Id":"",
         "Name":"",
         "CompanyId":"",
         "Employee":[
            {  
               "Id":"",
               "Name":"",
               "DepartmentId":""
            },
            {  
               "Id":"",
               "Name":"",
               "DepartmentId":""
            }
         ]
      }
   ]
}

也许我缺少一些东西。如果您在Heirachy中创建需要的类,请使用数据实例化,然后将它们序列化,将为您创建结构。

using System.Web.Script.Serialization;
public class Employee 
{
   public int Id {get; set; }
   public string Name {get; set; }
   public int DepartmentId {get; set; }   
}
public class Department 
{
   public int Id {get; set; }
   public string Name {get; set; }
   public string CompanyId {get; set; }
   public List<Employee> {get; set;}
}
public class Company {
   public int Id {get; set; }
   public string Name {get; set; }
   public string Location {get; set; }
   public List<Department> {get; set;}
}
var myCompany = new Company();
// add departments and employees
var json = new JavaScriptSerializer().Serialize(myCompany);

您可以使用 dynamic

//here your database
dynamic[] company = new object[] { new { Name = "Company1", DepartmentId = 1 }, new { Name = "Company2", DepartmentId = 2 } };
dynamic[] department = new object[] { new { DepartmentId = 1, Name = "Department1" }, new { DepartmentId = 2, Name = "Department2" } };
//select from database
var data = from c in company
    join d in department on c.DepartmentId equals d.DepartmentId
    select new {Name = c.Name, Department = d};
var serialized = JsonConvert.SerializeObject(data);

结果:

[
  {
    "Name": "Company1",
    "Department": {
      "DepartmentId": 1,
      "Name": "Department1"
    }
  },
  {
    "Name": "Company2",
    "Department": {
      "DepartmentId": 2,
      "Name": "Department2"
    }
  }
]

好吧,让我们尝试这样。首先,据我了解您的预先误解:您有父母和孩子的属性数组将其转换为JSON对象。关键是在这里:

public static ExpandoObject DicTobj(Dictionary<string, object> properties)
        {
            var eo = new ExpandoObject();
            var eoColl = (ICollection<KeyValuePair<string, object>>)eo;
            foreach (var childColumn in properties)
                eoColl.Add(childColumn);
            return eo;
        }

u使用 Dynamic ExpandOobject 将字典转换为对象

另一个代码很微不足道:您使用 dynamic 类型将所有对象都放在一个对象 并序列化。

完整代码:

public static Child Child1 { get; set; } = new Child
        {
            Name = "Child1"
        };
        public static Parent Parent1 { get; set; } = new Parent
        {
            Name = "Parent1"
        };
        public static Parent Parent2 { get; set; } = new Parent
        {
            Name = "Parent2"
        };
        private static void Main(string[] args)
        {
            var result = GetData(Child1, new List<Parent> {Parent1, Parent2});
            Console.WriteLine(result);
        }
        /// <summary>
        ///     This is the magic: convert dictionary of properties to object with preperties
        /// </summary>
        public static ExpandoObject DicTobj(Dictionary<string, object> properties)
        {
            var eo = new ExpandoObject();
            var eoColl = (ICollection<KeyValuePair<string, object>>) eo;
            foreach (var childColumn in properties)
                eoColl.Add(childColumn);
            return eo;
        }
        public static string GetData(Child model, List<Parent> parents)
        {
            var childColumns = GetColumns(model);
            dynamic child = DicTobj(childColumns);
            var parentsList = new List<object>();
            foreach (var parent in parents)
            {
                var parentColumns = GetColumns(parent);
                var parentObj = DicTobj(parentColumns);
                parentsList.Add(parentObj);
            }
            child.Parents = parentsList;
            return JsonConvert.SerializeObject(child);
        }

        /// <summary>
        ///     this is STUB method for example
        ///     I change return type from string[] to Dictionary[columnName,ColumnValue], becouse u need not only column names, but
        ///     with it values, i gues. If not, look commented example at the end of this method
        /// </summary>
        public static Dictionary<string, object> GetColumns(object model)
        {
            var result = new Dictionary<string, object>();
            if (model == Child1)
            {
                result.Add("Id", "1");
                result.Add("Name", "Child1");
                result.Add("Location", "SomeLocation");
            }
            if (model == Parent1)
            {
                result.Add("Id", "2");
                result.Add("Name", "Parent1");
                result.Add("SomeProperty1", "SomeValue1");
            }
            if (model == Parent2)
            {
                result.Add("Id", "3");
                result.Add("Name", "Parent1");
                result.Add("SomeProperty3", "SomeValue2");
            }
            //if u have only columNames and dont need values u can do like this
            //var columns = new[] {"Id", "Name", "SomeProperty1"};//this u get from DB
            //return columns.ToDictionary(c => c, c => new object());
            return result;
        }
    }
    public class Child
    {
        public string Name { get; set; } // Contains Employee
        //Other properties and info related to process sql query and connection string
    }
    public class Parent
    {
        public string Name { get; set; } // Contains Company,Department.
        public string SqlQuery { get; set; } // query related to Company and Department.
        //Other properties and info related to connection string
    }

和结果输出:

{
  "Id": "1",
  "Name": "Child1",
  "Location": "SomeLocation",
  "Parents": [
    {
      "Id": "2",
      "Name": "Parent1",
      "SomeProperty1": "SomeValue1"
    },
    {
      "Id": "3",
      "Name": "Parent1",
      "SomeProperty3": "SomeValue2"
    }
  ]
}

即使没有固定结构,也可以传递任何类型的对象:

Newtonsoft.Json.JsonConvert.SerializeObject(new yourCustomObject)

使用此。

获得此结果的最佳方法
- 您必须创建一个具有所有班级关系的新类。然后使用 newtonsoft.json.jsonconvert.serializeobject(新组织)
让我们创建一个名为"组织"的新类。添加您想在JSON中看到的关系。然后使用JSONCONVERT转换为JSON。
或者您可以使用以下动态循环

//here your database<br/>
dynamic[] company = new object[] { new { Name = "Company1", DepartmentId = 1 }, new { Name = "Company2", DepartmentId = 2 } };

dynamic [] dementment = new Object [] {new {new {depptiond = 1,name =" dectment1"},new {depptiondID = 2,name =" dectment2"}};

//select from database<br/>
var data = from c in company
    join d in department on c.DepartmentId equals d.DepartmentId
    select new {Name = c.Name, Department = d};

var serialized = JsonConvert.SerializeObject(data);

相关内容

  • 没有找到相关文章

最新更新