使用MySqlDataAdapter时如何解决“给定键不在字典中”错误
我来帮你一步步排查和解决这个错误,System.Collections.Generic.KeyNotFoundException提示“给定的键不在字典中”,通常有几个明确的触发点,我们一个个来搞定:
1. 先查连接字符串配置(最可能的原因)
你的DataManager类里用了ConfigurationManager.ConnectionStrings["cnn1"],首先要确认你的项目配置文件(Web.config,因为是ASP.NET项目)里确实存在名为cnn1的连接字符串。正确的配置格式应该是这样的:
<connectionStrings> <add name="cnn1" connectionString="server=localhost;user id=root;password=你的XAMPP数据库密码;database=你的数据库名;persistsecurityinfo=True" providerName="MySql.Data.MySqlClient" /> </connectionStrings>
如果cnn1这个键在配置里找不到,程序一访问ConnectionStrings["cnn1"]就会直接抛出这个错误,这是最常见的触发原因。
2. 修复存储过程的SQL错误
你的存储过程里的SELECT语句写了SELECT 'P_id','name','unit_price','image_product' FROM product——这里的单引号会把列名变成固定字符串,而不是查询product表中的实际列。正确的写法应该去掉单引号:
DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `product_select`() NO SQL SELECT P_id, name, unit_price, image_product FROM product$$ DELIMITER ;
原来的写法会返回一行四个字符串值(就是你写的那几个列名字符串),而不是表中的真实数据,后续绑定DataList时也可能引发其他异常。
3. 修正DataSet的using用法(规范代码)
DataSet是内存中的数据集,虽然它实现了IDisposable,但它的Dispose方法主要是释放关联的事件,不会占用非托管资源,所以不需要用using包裹。你可以改成更简洁的写法:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { DataSet ds = DataManager.GetDataSet("product_select","x"); DataList1.DataSource = ds.Tables["x"]; DataList1.DataBind(); // 手动释放DataSet(可选,内存会自动回收) ds.Dispose(); } }
当然如果坚持用using也没问题,但这不是引发当前错误的原因。
4. 完善DataManager的资源释放逻辑
你的GetDataSet方法里没有释放数据库连接、命令这些非托管资源,这会导致数据库连接泄漏,时间长了会出问题。应该用using语句自动释放这些资源:
public static DataSet GetDataSet(string stored_name, string table_name, params MySqlParameter[] prmarr) { DataSet ds = new DataSet(); // using会自动调用Dispose,确保连接关闭 using (MySqlConnection con = new MySqlConnection(constr)) using (MySqlCommand cmd = new MySqlCommand(stored_name,con)) using (MySqlDataAdapter da = new MySqlDataAdapter(cmd)) { cmd.CommandType = CommandType.StoredProcedure; foreach (MySqlParameter prm in prmarr) { cmd.Parameters.Add(prm); } da.Fill(ds,table_name); } return ds; }
排查顺序建议
- 先检查Web.config里的
cnn1连接字符串是否存在,这是触发当前错误的最直接原因; - 修复存储过程的SQL语句,确保能拿到正确的数据;
- 完善DataManager的资源释放,避免后续的连接池问题;
- 调整DataSet的使用方式,符合.NET的最佳实践。
内容的提问来源于stack exchange,提问作者mohamed elkordy

