选择cmbSitePSI组合框选项后无法自动填充关联文本框问题求助
问题核心原因
SqlDataReader.GetString()方法仅支持传入整数类型的列索引,不支持直接传入列名字符串,这是你代码行报波浪线的直接原因。- 原有代码存在SQL字符串拼接的注入风险,同时存在数据库连接重复打开、资源未释放、组合框取值错误(写了
cmbSitePSI而非cmbSitePSI.Text/SelectedValue)的问题。 - 未处理组合框初始加载时
SelectedIndexChanged事件触发的空值异常。

正确实现代码
1. 窗体加载时绑定组合框数据源
private void 你的窗体名_Load(object sender, EventArgs e) { string constring = "Data Source=*********;Initial Catalog=DIETS;Integrated Security=True"; // using语法会自动释放数据库连接资源,无需手动关闭 using (SqlConnection con = new SqlConnection(constring)) { con.Open(); SqlDataAdapter da = new SqlDataAdapter(@"SELECT SitePSI FROM Site ORDER BY SitePSI", con); DataTable dt = new DataTable(); da.Fill(dt); // 绑定组合框显示值和实际值 cmbSitePSI.DataSource = dt; cmbSitePSI.DisplayMember = "SitePSI"; cmbSitePSI.ValueMember = "SitePSI"; } }
2. 组合框选中变化事件实现自动填充
private void CmbSitePSI_SelectedIndexChanged(object sender, EventArgs e) { // 跳过组合框初始加载无选中值的场景,避免报错 if (cmbSitePSI.SelectedValue == null) return; string constring = "Data Source=*********;Initial Catalog=DIETS;Integrated Security=True"; // 全程用参数化查询,避免SQL注入风险和类型转换错误 string query = @"SELECT SiteName, SiteLongName, SiteAddress1, SiteAddress2, SiteAddress3, SiteCity, SiteState, SiteZipCode, SiteCountry, SiteOperationsRegion FROM Site WHERE SitePSI = @SitePSI"; using (SqlConnection condata = new SqlConnection(constring)) using (SqlCommand cmddata = new SqlCommand(query, condata)) { // 明确指定参数类型,匹配数据库字段类型 cmddata.Parameters.Add("@SitePSI", SqlDbType.Int).Value = (int)cmbSitePSI.SelectedValue; try { condata.Open(); using (SqlDataReader r = cmddata.ExecuteReader()) { // SitePSI是唯一值,用if判断即可,不需要循环 if (r.Read()) { // 两种正确的字段取值方式二选一即可: // 方式1:先获取列索引再调用GetString txtSiteName.Text = r.GetString(r.GetOrdinal("SiteName")); txtSiteLName.Text = r.GetString(r.GetOrdinal("SiteLongName")); // 方式2:直接转字符串,写法更简洁 // txtSiteName.Text = r["SiteName"].ToString(); // txtSiteLName.Text = r["SiteLongName"].ToString(); // 剩余地址、城市等字段按照同样逻辑赋值给对应文本框即可 // txtSiteAddress1.Text = r["SiteAddress1"].ToString(); // ... 依次补全所有字段赋值 } else { // 无匹配数据时清空所有文本框 txtSiteName.Clear(); txtSiteLName.Clear(); // 其他文本框也同步清空 } } } catch (Exception ex) { MessageBox.Show("数据加载失败:" + ex.Message); } } }
注意事项
- 如果数据库中对应字段允许为空,取值时需要先判断是否为
DBNull,避免空引用报错,示例:txtSiteName.Text = r["SiteName"]?.ToString() ?? ""; - 不需要额外维护全局的数据库连接对象,用
using每次按需创建连接即可,ADO.NET会自动管理连接池,性能不会受影响。
内容的提问来源于stack exchange,提问作者Anthony Mullins
相关产品推荐
相关产品推荐

