You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历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 = @Category
    
    然后在代码中一次性读取所有数据,再分组构建PriceDetail对象,这样只需要一次数据库连接和查询,效率更高。

内容的提问来源于stack exchange,提问作者Ahsan Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:32:59