遍历PriceDetail对象列表时Items属性被覆盖的问题求助
问题原因分析
你遇到的这个问题是引用类型的特性导致的。在你的代码里,List<string> items = new List<string>();是在第二个while循环外面声明的——也就是说所有PriceDetail对象的Items属性都指向同一个List实例。当你执行items.Clear()时,所有引用这个列表的PriceDetail的Items都会被清空;而在下一次循环添加新元素时,所有指向这个列表的对象都会同步看到新内容,这就导致了后面的元素会覆盖前面的Items值。
修复方案
只需要把items列表的创建移到第二个while循环内部,让每个PriceDetail都拥有独立的List实例即可。同时我也帮你优化了数据库资源的使用(用using语句自动释放连接,避免泄漏):
public class PriceDetail { public int ID{ get; set; } public string Package { get; set; } public string Currency { get; set; } public int Price { get; set; } public string PackageType { get; set; } public List<string> Items { get; set; } } [WebMethod] public static string GetCardDetail(string category) { string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString; List<PriceDetail> pricingCard = new List<PriceDetail>(); string query = "select [PricingID],[Package],[Currency],[Price],[PackageType] from [SeoDatabase].[dbo].[tbl_Pricing] where Category = @Category"; // 使用using自动释放连接资源 using(SqlConnection con = new SqlConnection(cs)) { SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@Category", category); con.Open(); SqlDataReader rdr = cmd.ExecuteReader(); while (rdr.Read()) { PriceDetail priceDetail = new PriceDetail(); // 注意:如果数据库的PricingID和Price是int类型,建议用Convert.ToInt32避免溢出 priceDetail.ID = Convert.ToInt32(rdr["PricingID"]); priceDetail.Package = rdr["Package"].ToString(); priceDetail.Currency = rdr["Currency"].ToString(); priceDetail.Price = Convert.ToInt32(rdr["Price"]); priceDetail.PackageType = rdr["PackageType"].ToString(); pricingCard.Add(priceDetail); } } string queryList = "select [Item] from [SeoDatabase].[dbo].[tbl_PricingItem] where PricingID = @pricingID"; int i = 0; while(i < pricingCard.Count) { // 每次循环创建新的items列表,确保每个PriceDetail的Items都是独立实例 List<string> items = new List<string>(); using(SqlConnection con = new SqlConnection(cs)) { SqlCommand listCmd = new SqlCommand(queryList, con); listCmd.Parameters.AddWithValue("@pricingID", pricingCard[i].ID); con.Open(); SqlDataReader listReader = listCmd.ExecuteReader(); while (listReader.Read()) { items.Add(listReader["Item"].ToString()); } } pricingCard[i].Items = items; i++; } string obj = JsonConvert.SerializeObject(pricingCard); return obj; }
额外优化建议
- 始终用
using语句包裹SqlConnection、SqlCommand、SqlDataReader,确保资源被正确释放,避免数据库连接泄漏。 - 检查数据库中
PricingID和Price字段的类型,如果是int(32位整数),用Convert.ToInt32比Convert.ToInt16更安全,防止数据溢出。 - 可以考虑合并两次数据库查询为一次联表查询,减少数据库交互次数提升性能:
然后在代码中一次性读取所有数据,再分组构建SELECT p.PricingID, p.Package, p.Currency, p.Price, p.PackageType, pi.Item FROM tbl_Pricing p LEFT JOIN tbl_PricingItem pi ON p.PricingID = pi.PricingID WHERE p.Category = @CategoryPriceDetail对象,这样只需要一次数据库连接和查询,效率更高。
内容的提问来源于stack exchange,提问作者Ahsan Ali
相关产品推荐
相关产品推荐

