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

代码问题排查:为何从SQL获取的List<Menu>中菜品重复?

问题分析与解决方案

嘿,我一眼就揪出问题啦!你把Menu对象的实例化代码放在了while循环外面,这就导致整个循环过程中你一直在修改同一个对象的属性,然后反复把这个对象添加到列表里。因为C#中列表存储的是对象的引用,而不是对象本身的副本,所以最后你看到的所有菜品数据都是最后一次读取到的值——本质上列表里全是同一个Menu对象的引用,自然会全部重复。

举个简单的例子:第一次循环你给menu的Tenmon和Loaimon赋值,把它加到列表;第二次循环你又修改同一个menu的这两个属性,这时候列表里的第一个元素其实也是这个menu的引用,它的值也会跟着改变;直到循环结束,列表里的所有元素都指向这个唯一的Menu对象,显示的自然都是最后一次读取的菜品信息。

修改后的代码

把Menu的实例化移到while循环内部,每次循环都创建一个全新的对象:

public List<Menu> Getmonan() 
{ 
    string cs = ConfigurationManager.ConnectionStrings["RestaurantConnection"].ConnectionString; 
    List<Menu> menulist = new List<Menu>(); 

    using (SqlConnection conn = new SqlConnection(cs)) 
    { 
        SqlCommand cmd = new SqlCommand("Getmenu", conn); 
        cmd.CommandType = CommandType.StoredProcedure; 
        conn.Open(); 
        SqlDataReader reader = cmd.ExecuteReader(); 
        
        while(reader.Read()) 
        { 
            // 每次循环创建新的Menu实例,避免引用重复
            Menu menu = new Menu(); 
            menu.Tenmon = reader["TenMon"].ToString(); 
            menu.Loaimon = reader["LoaiMon"].ToString(); 
            menulist.Add(menu); 
        }
        
        // 可选:显式关闭DataReader,虽然using块结束时会自动处理,但显式关闭更规范
        reader.Close();
    } 
    
    return menulist; 
}

额外小提示

  • 确保你的Menu类是普通的POCO(简单旧CLR对象),没有静态属性或者共享的引用类型成员,否则可能还会出现类似的状态共享问题。
  • 如果你需要更高效的对象创建,也可以考虑在循环外复用对象,但每次添加前必须创建新的副本(比如通过克隆或者重新赋值新实例),不过对于这种场景,直接在循环内实例化是最清晰不易出错的方式。

内容的提问来源于stack exchange,提问作者Hau Le

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:00:16