C#中ComboBox绑定SQL数据后取值报错:字符串格式不正确
问题描述(中文翻译)
我正在学习C#中SQL的使用,遇到了一个解决不了的问题。我做了一个从数据库读取数据的ComboBox,想把数据库的Id设为ValueMember,显示Title字段的内容。点击按钮时,我希望通过选中项的Id,把对应行的Story字段内容写入RichTextBox,但运行时出现错误:
String was not in correct format
数据库结构如下:
| Id | Title | Author | Story |
|---|---|---|---|
| 1 | aTitle | Me | Random Text |
| 2 | SomeTitle | NotMe | More Random Text |
我的代码如下:
private void LoadData() { using (Connection = new SqlConnection(ConnectionString)) //创建连接 using (Adapter = new SqlDataAdapter("SELECT Title FROM StoryTable", ConnectionString)) { Connection.Open(); DataTable TitleTable = new DataTable(); Adapter.Fill(TitleTable); SelectionBox.ValueMember = "Id"; SelectionBox.DisplayMember = "Title"; SelectionBox.DataSource = TitleTable; } } private void LoadButton_Click(object sender, EventArgs e) { int Id = Int32.Parse(SelectionBox.ValueMember); //报错:String was not in correct format using (Connection = new SqlConnection(ConnectionString)) using (Adapter = new SqlDataAdapter("SELECT Story FROM StoryTable", ConnectionString)) { Connection.Open(); var TextTable = new DataSet(); Adapter.Fill(TextTable); StoryTextbox.Text = TextTable.Tables[0].Rows[Id]["Story"].ToString(); } }
问题根源及修正方案
1. 数据加载时缺少Id字段
LoadData方法的SQL仅查询了Title,但你把ValueMember设为Id——此时DataTable中没有Id列,ComboBox无法绑定到正确的数值,后续解析必然出错。
修正:修改SQL语句,同时查询Id和Title:
SELECT Id, Title FROM StoryTable
2. 错误获取选中项的Id值
SelectionBox.ValueMember是用来指定值成员字段名称的字符串(即你设置的"Id"),不是选中项的实际值。要获取选中项的Id,应该用SelectionBox.SelectedValue。
另外直接用Int32.Parse风险高,建议用int.TryParse做安全转换,避免空值或非数字场景。
3. 查询Story时未按Id筛选
当前SQL查询所有Story,再用Id作为行索引取值——逻辑错误,数据库的Id不一定等于DataTable的行索引(比如删除过数据会导致Id断号)。正确做法是用参数化查询,根据选中的Id精准获取对应内容。
修正后的完整代码
private void LoadData() { // 同时查询Id和Title,确保DataTable包含所需字段 using (var adapter = new SqlDataAdapter("SELECT Id, Title FROM StoryTable", ConnectionString)) { DataTable titleTable = new DataTable(); adapter.Fill(titleTable); SelectionBox.ValueMember = "Id"; SelectionBox.DisplayMember = "Title"; SelectionBox.DataSource = titleTable; } } private void LoadButton_Click(object sender, EventArgs e) { // 安全转换选中的Id值 if (SelectionBox.SelectedValue == null || !int.TryParse(SelectionBox.SelectedValue.ToString(), out int selectedId)) { MessageBox.Show("请选择有效的条目"); return; } // 参数化查询,根据Id获取对应Story string query = "SELECT Story FROM StoryTable WHERE Id = @Id"; using (var connection = new SqlConnection(ConnectionString)) using (var adapter = new SqlDataAdapter(query, connection)) { // 添加参数,避免SQL注入 adapter.SelectCommand.Parameters.AddWithValue("@Id", selectedId); DataTable storyTable = new DataTable(); adapter.Fill(storyTable); if (storyTable.Rows.Count > 0) { StoryTextbox.Text = storyTable.Rows[0]["Story"].ToString(); } else { StoryTextbox.Text = ""; MessageBox.Show("未找到对应内容"); } } }
额外提示
- 不要把
Connection和Adapter作为类成员变量,方法内声明局部变量更安全,避免连接泄漏。 - 参数化查询可有效防止SQL注入,同时避免字符串拼接导致的语法错误。
- 处理
SelectedValue时必须做空值判断,防止用户未选择任何项就点击按钮的情况。
内容的提问来源于stack exchange,提问作者Merv
相关产品推荐
相关产品推荐

