将 C# 对象序列化为包含列表的 JSON
Serialize C# object into JSON which contains a List
我想做的是从我的数据库中获取一些数据(客户订购他订购的所有商品)将其转换为 JSON,其中包含所述商品的列表,以便我可以将其发送POST 请求。
我想创建一个 JSON 对象,其中包含客户订单的详细信息以及该订单中包含的产品列表。这就是我希望我的 JSON 看起来像的样子:
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 0,
"product_Price ": "105.00",
"order_Item_Rebate: "",
"product_code": "000001",
"quantity": 1
},
{
"item_id": 1,
"product_Price ": "55.00",
"price": "",
"product_code": "000002",
"quantity": 5
},
{
"item_id": 2,
"product_Price ": "15.00",
"price": "",
"product_code": "000003",
"quantity": 3
}
]
}
但我得到的是:
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 0,
"roduct_Price ": "105.00",
"order_Item_Rebate: "",
"product_code": "000001",
"quantity": 1
}
]
},
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 1,
"roduct_Price ": "55.00",
"price": "",
"product_code": "000002",
"quantity": 5
}
]
},
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 2,
"product_Price ": "15.00",
"price": "",
"product_code": "000003",
"quantity": 3
}
]
}
我得到了同一个客户 (account_code) 的多个 JSON 对象,而不是一个带有项目列表的 JSON 对象。
我使用 ADO.NET 从数据库中获取此数据,并使用 SqlDataReader 读取此数据。在 SqlDataReader 中,我创建了一个新对象并在其中填充了有关我的订单的详细信息。一切正常,但问题是 order_items 它应该是订单中所有项目的列表。我想要一个包含多个项目的订单,而不是每个项目的不同订单。
使用下面的代码我可以从我的数据库中获取数据,但我不知道如何将 order_items 按照它们应该在的顺序进行分组。
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
OrderModel order = new OrderModel()
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
{
//Here is where I should do something instead of creating new
//Order_items, but I don't know what
new Order_items()
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
}
}
};
orderList.Add(order);
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
我的 OrderModel class 看起来像这样:
public class OrderModel
{
public string Account_code { get; set; }
public bool Advance_payment { get; set; }
public DateTime Date { get; set; }
public List<Order_items> Order_Items { get; set; }
}
public class Order_items
{
public string Order_Item_Rebate { get; set; }
public string Product_Price { get; set; }
public string Product_Code { get; set; }
public string Quantity { get; set; }
}
我的数据库中的 table 如下所示:
Account_code
Order_Item_Rebate
Product_Price
Product_Code
Quantity
00000
10
105
000001
1
00000
5
55
000002
5
00000
15
15
000002
3
我见过类似的问题,人们建议使用一系列词典,但我不确定我是否理解它们会有什么帮助。我是新手,如果问题不是很聪明,我很抱歉。
- 在
while
循环之外定义您的 order
变量。
var order = new OrderModel()
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
- 在
while
循环中解析订单项
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
var item = new Order_items()
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
};
order.Order_Items.Add(item);
}
}
- 序列化循环后唯一的
OrderModel
var jsonString = JsonConvert.SerializeObject(order);
return jsonString;
SQL查询会得到“扁平化”的数据,所以需要自己分组。沿着这条线:
var orderDict = new Dictionary<string, OrderModel>(); // mapping from account code to order object
while (rdr.Read())
{
var accCode = rdr[0].ToString();
// if no object previously added - add a new one
if(!orderDict.TryGetValue(accCode, out var order))
{
order = new OrderModel()
{
Account_code = accCode ,
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderDict[accCode] = order;
}
// add details from current result line to order
order.Order_Items.Add(new Order_items() {...});
}
var jsonString = JsonConvert.SerializeObject(orderDict.Values); // serialize only values, not the whole dictionary
因此,问题在于您在 while (rdr.Read())
循环的每次迭代中都创建了一个新的 OrderModel
。最直接的方法是根据 Account_code
简单地检查 orderList
中的现有 OrderModel
,并仅在以下情况下创建 OrderModel
的新实例找不到一个。例如...
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
// Check to see if there is already an instance of OrderModel with the
// account code in the list.
OrderModel order = orderList.FirstOrDefault(om => om.Account_code == rdr[0].ToString());
if (order == null)
{
// If there isn't create a new instance of OrderModel and add it to
// the list.
order = new OrderModel
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderList.Add(order);
}
// Now, just add the new item to Order_Items.
order.Order_Items.Add(new Order_item
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
});
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
性能可能很差,尤其是当 orderList
变大时,因为您在 while
循环的每次迭代中迭代一次 orderList
。但是,这种基本方法应该有效。不是在 while
循环的每次迭代中创建一个 OrderModel
,而是需要确保只在结果集中的每个 Account_code
上创建。
如果您可以控制查询本身,则可以按 Account_code
对结果进行排序以解决性能问题。
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
OrderModel order = null;
while (rdr.Read())
{
if (order == null || order.Account_code != rdr[0].ToString())
{
// The order is null, meaning that this is the first order model to be processed.
// Or, the order's account code is different than the current account code on the result set, meaning we have begun processing a new order.
// In either case, you need to add a new order to the list so
// you can start filling in its items.
order = new OrderModel
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderList.Add(order);
}
// Now, just add the new item to Order_Items.
order.Order_Items.Add(new Order_item
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
});
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
上述方法只有在您可以按帐户代码对查询结果进行排序时才有效。
我想做的是从我的数据库中获取一些数据(客户订购他订购的所有商品)将其转换为 JSON,其中包含所述商品的列表,以便我可以将其发送POST 请求。 我想创建一个 JSON 对象,其中包含客户订单的详细信息以及该订单中包含的产品列表。这就是我希望我的 JSON 看起来像的样子:
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 0,
"product_Price ": "105.00",
"order_Item_Rebate: "",
"product_code": "000001",
"quantity": 1
},
{
"item_id": 1,
"product_Price ": "55.00",
"price": "",
"product_code": "000002",
"quantity": 5
},
{
"item_id": 2,
"product_Price ": "15.00",
"price": "",
"product_code": "000003",
"quantity": 3
}
]
}
但我得到的是:
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 0,
"roduct_Price ": "105.00",
"order_Item_Rebate: "",
"product_code": "000001",
"quantity": 1
}
]
},
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 1,
"roduct_Price ": "55.00",
"price": "",
"product_code": "000002",
"quantity": 5
}
]
},
{
"account_code": "00000",
"advance_payment": false,
"date": [today's date],
"order_items":
[
{
"item_id": 2,
"product_Price ": "15.00",
"price": "",
"product_code": "000003",
"quantity": 3
}
]
}
我得到了同一个客户 (account_code) 的多个 JSON 对象,而不是一个带有项目列表的 JSON 对象。
我使用 ADO.NET 从数据库中获取此数据,并使用 SqlDataReader 读取此数据。在 SqlDataReader 中,我创建了一个新对象并在其中填充了有关我的订单的详细信息。一切正常,但问题是 order_items 它应该是订单中所有项目的列表。我想要一个包含多个项目的订单,而不是每个项目的不同订单。 使用下面的代码我可以从我的数据库中获取数据,但我不知道如何将 order_items 按照它们应该在的顺序进行分组。
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
OrderModel order = new OrderModel()
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
{
//Here is where I should do something instead of creating new
//Order_items, but I don't know what
new Order_items()
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
}
}
};
orderList.Add(order);
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
我的 OrderModel class 看起来像这样:
public class OrderModel
{
public string Account_code { get; set; }
public bool Advance_payment { get; set; }
public DateTime Date { get; set; }
public List<Order_items> Order_Items { get; set; }
}
public class Order_items
{
public string Order_Item_Rebate { get; set; }
public string Product_Price { get; set; }
public string Product_Code { get; set; }
public string Quantity { get; set; }
}
我的数据库中的 table 如下所示:
Account_code | Order_Item_Rebate | Product_Price | Product_Code | Quantity |
---|---|---|---|---|
00000 | 10 | 105 | 000001 | 1 |
00000 | 5 | 55 | 000002 | 5 |
00000 | 15 | 15 | 000002 | 3 |
我见过类似的问题,人们建议使用一系列词典,但我不确定我是否理解它们会有什么帮助。我是新手,如果问题不是很聪明,我很抱歉。
- 在
while
循环之外定义您的order
变量。
var order = new OrderModel()
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
- 在
while
循环中解析订单项
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
var item = new Order_items()
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
};
order.Order_Items.Add(item);
}
}
- 序列化循环后唯一的
OrderModel
var jsonString = JsonConvert.SerializeObject(order);
return jsonString;
SQL查询会得到“扁平化”的数据,所以需要自己分组。沿着这条线:
var orderDict = new Dictionary<string, OrderModel>(); // mapping from account code to order object
while (rdr.Read())
{
var accCode = rdr[0].ToString();
// if no object previously added - add a new one
if(!orderDict.TryGetValue(accCode, out var order))
{
order = new OrderModel()
{
Account_code = accCode ,
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderDict[accCode] = order;
}
// add details from current result line to order
order.Order_Items.Add(new Order_items() {...});
}
var jsonString = JsonConvert.SerializeObject(orderDict.Values); // serialize only values, not the whole dictionary
因此,问题在于您在 while (rdr.Read())
循环的每次迭代中都创建了一个新的 OrderModel
。最直接的方法是根据 Account_code
简单地检查 orderList
中的现有 OrderModel
,并仅在以下情况下创建 OrderModel
的新实例找不到一个。例如...
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
while (rdr.Read())
{
// Check to see if there is already an instance of OrderModel with the
// account code in the list.
OrderModel order = orderList.FirstOrDefault(om => om.Account_code == rdr[0].ToString());
if (order == null)
{
// If there isn't create a new instance of OrderModel and add it to
// the list.
order = new OrderModel
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderList.Add(order);
}
// Now, just add the new item to Order_Items.
order.Order_Items.Add(new Order_item
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
});
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
性能可能很差,尤其是当 orderList
变大时,因为您在 while
循环的每次迭代中迭代一次 orderList
。但是,这种基本方法应该有效。不是在 while
循环的每次迭代中创建一个 OrderModel
,而是需要确保只在结果集中的每个 Account_code
上创建。
如果您可以控制查询本身,则可以按 Account_code
对结果进行排序以解决性能问题。
List<OrderModel> orderList = new List<OrderModel>();
using (SqlDataReader rdr = await cmd.ExecuteReaderAsync())
{
OrderModel order = null;
while (rdr.Read())
{
if (order == null || order.Account_code != rdr[0].ToString())
{
// The order is null, meaning that this is the first order model to be processed.
// Or, the order's account code is different than the current account code on the result set, meaning we have begun processing a new order.
// In either case, you need to add a new order to the list so
// you can start filling in its items.
order = new OrderModel
{
Account_code = rdr[0].ToString(),
Advance_payment = false,
Date = DateTime.Now.Date,
Order_Items = new List<Order_items>()
};
orderList.Add(order);
}
// Now, just add the new item to Order_Items.
order.Order_Items.Add(new Order_item
{
Order_Item_Rebate = rdr[1].ToString(),
Product_Price = rdr[2].ToString(),
Product_Code = rdr[3].ToString(),
Quantity = rdr[4].ToString()
});
}
var jsonString = JsonConvert.SerializeObject(orderList);
return jsonString;
}
上述方法只有在您可以按帐户代码对查询结果进行排序时才有效。