C# WinForm按城市加载数据库图片到FlowLayoutPanel报列名无效怎么解决
错误原因
你的报错是由于GetID方法中拼接SQL语句时,字符串类型的查询值没有添加单引号导致的:
你写的command.CommandText = $"Select * from Photos where City = {City}";最终生成的SQL语句为Select * from Photos where City = London,数据库会把London识别为列名而非字符串类型的查询值,因此抛出「无效列名」的异常。
同时你当前的逻辑存在性能冗余:先按城市查询所有PhotoID,再循环每个ID单独查询一次数据库加载图片,会产生大量不必要的数据库连接与查询请求。
解决方案
最优方案:改用参数化查询(推荐)
和你已有的图片插入逻辑保持一致,使用参数化传递查询值,既可以避免引号匹配问题,还能防范SQL注入风险,修改GetID方法中SQL相关代码即可:
private void GetID(string City, FlowLayoutPanel flp) { try { using (SqlConnection conn = new SqlConnection()) { conn.ConnectionString = Settings.Default.Database1ConnectionString; conn.Open(); SqlCommand command = new SqlCommand(); // 改用参数占位符 command.CommandText = "Select * from Photos where City = @City"; // 添加参数赋值 command.Parameters.Add("@City", SqlDbType.Text).Value = City; command.Connection = conn; SqlDataReader DR = command.ExecuteReader(); while (DR.Read()) { loadImage((int)DR["PhotoID"], flp); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
临时方案(不推荐):手动加单引号拼接
如果不想改参数化,可以手动给字符串值加单引号,但是如果城市名本身包含单引号时仍会报错,不建议长期使用:
command.CommandText = $"Select * from Photos where City = '{City}'";
性能优化建议
你可以把两次查询的逻辑合并,直接按城市查询所有图片数据,减少数据库交互次数,优化后的参考代码如下:
private void LoadCityImages(string city, FlowLayoutPanel flp) { try { flp.Controls.Clear(); using (SqlConnection conn = new SqlConnection(Settings.Default.Database1ConnectionString)) { conn.Open(); // 一次查询直接获取对应城市的所有图片 SqlCommand command = new SqlCommand("Select Image from Photos where City = @City", conn); command.Parameters.Add("@City", SqlDbType.Text).Value = city; using (SqlDataReader DR = command.ExecuteReader()) { while (DR.Read()) { byte[] bytes = (byte[])DR["Image"]; using (MemoryStream MS = new MemoryStream(bytes)) { PictureBox pics = new PictureBox(); pics.Image = Image.FromStream(MS); pics.Size = new Size(200, 160); pics.SizeMode = PictureBoxSizeMode.StretchImage; flp.Controls.Add(pics); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } // 对应伦敦按钮的点击事件修改为 private void button1_Click(object sender, EventArgs e) { LoadCityImages("London", flowLayoutPanel1); }
内容的提问来源于stack exchange,提问作者YS Chang
相关产品推荐
相关产品推荐

