我正在尝试为层次结构生成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
}
答案 0 :(得分:2)
也许我错过了什么。如果您在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);
答案 1 :(得分:2)
更新:
好的,再试一次。
我创建了一个类,它在子父结构中与您提议的内容类似地保存信息。我还添加了一个递归工作的自定义小分析器。也许这就是你需要什么和/或什么能为你提供解决问题所需的想法。
我还通过添加有角度的括号(“[]”)来稍微改变输出。我想这就是你需要多个孩子的东西。至少那就是JSON验证器告诉我的,我发布在下面。如果您不需要/想要它们,只需在解析器中删除它们。
我不认为你可以使用你在你的例子中使用的解析器,而没有我在之前的答案中显示的某些形式的额外字段,因为那些解析器通常将属性名称作为字段,我想你不想创建类在运行时动态。
我也不认为你可以用Lists,Arrays或Dictionaries创建一个动态深度的亲子 - 孩子......关系,因为这些结构一旦有了设定深度宣布。
希望这会有所帮助。如果没有,请告诉我。
班级:
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":""
}
]
}
]
}
答案 2 :(得分:1)
您可以使用动态:
//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"
}
}
]
答案 3 :(得分:1)
好的,我们试试吧。首先,因为我理解你的preblem:你有父母和孩子的属性数组,你需要将它转换为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;
}
使用动态和 ExpandoObject 将字典转换为对象
其他代码很简单:您使用动态类型将所有对象放到一个 并序列化它。
完整代码:
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"
}
]
}
答案 4 :(得分:1)
即使您没有固定的结构,也可以传递任何类型的对象:
Newtonsoft.Json.JsonConvert.SerializeObject(new yourCustomObject)
使用此功能。
答案 5 :(得分:1)
获得此结果的最佳方式
- 你必须创建一个具有所有类关系的新类。然后使用
Newtonsoft.Json.JsonConvert.SerializeObject(新组织)
让我们创建一个名为organization的新类。添加要在Json中查看的关系。然后使用JsonConvert转换为JSON。
或者您可以使用以下动态循环
//here your database<br/>
dynamic[] company = new object[] { new { Name = "Company1", DepartmentId = 1 }, new { Name = "Company2", DepartmentId = 2 } };
dynamic [] department = new object [] {new {DepartmentId = 1,Name =&#34; Department1&#34; },new {DepartmentId = 2,Name =&#34; Department2&#34; }};
//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);