【问题标题】:ASP .Net - MySql - Unable to read any dataASP .Net - MySql - 无法读取任何数据
【发布时间】:2012-10-09 19:07:15
【问题描述】:

我遇到了一个问题,不知道 WTF 正在发生。我有一个需要使用 Web 服务与 MySQL 数据库通信的 C# Web 应用程序。我可以使用方法来插入数据,但是每当我尝试读取任何内容(ExecuteReader 或 ExecuteScalar)时,它都会失败并显示以下非常奇怪的消息:

给定的键不在字典中。

现在,Web 服务使用此类与 db 进行通信:

 public class DatabaseHelper
{
    private MySqlCommand cmd;
    private MySqlConnection con;
    public DatabaseHelper()
    {
        String server = "localhost";
        String database = "testdb";
        String password = "password";
        String username = "root";


        String connString = "Server = " + server + "; Database = " + database + "; Uid = " + username + "; Pwd = " + password + "; default command timeout=60;";
        con = new MySqlConnection();
        con.ConnectionString = connString;

        cmd = new MySqlCommand();

        cmd.Connection = con;
    }

    public void RunExecuteNonQuery(string sql, MySqlParameter[] param)
    {
        try
        {

            cmd.CommandText = sql;
            if (param != null)
            {
                cmd.Parameters.AddRange(param);
            }
            cmd.CommandText = sql;
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
            cmd.Parameters.Clear();

        }
        catch (MySqlException ex)
        {
            con.Close();

        }
    }
    public object RunExecuteScalar(string sql, MySqlParameter[] param)
    {
        if (param != null)
        {
            cmd.Parameters.AddRange(param);
        }
        cmd.CommandText = sql;
        object ret;
        con.Open();
        ret = cmd.ExecuteScalar();
        con.Close();
        cmd.Parameters.Clear();
        return ret;
    }

    public MySqlDataReader RunExecuteDataReader(string sql, MySqlParameter[] param)
    {
        if (param != null)
        {
            cmd.Parameters.AddRange(param);
        }
        cmd.CommandText = sql;
        MySqlDataReader ret = null;

        con.Open();

       ret = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
       cmd.Parameters.Clear();


        return ret;
    }
}

在 cmd.ExecuteReader 或 cmd.ExecuteScalar 上失败!

另一方面,来自 Web 服务的方法如下所示:

 [WebMethod]
    public string[] GetCategories()
    {
        String sql = "SELECT * FROM category";
        DatabaseHelper dh = new DatabaseHelper();
        MySqlDataReader dr = dh.RunExecuteDataReader(sql, null);
        List<String> categories = new List<string>();
        while (dr.Read())
        {
            categories.Add(dr[0].ToString());
        }
        dr.Close();

        return categories.ToArray();
    }

这真的很奇怪,因为错误非常神秘(我根本没有使用字典),而且我在许多其他应用程序中都使用过同一个类。我在另一台计算机上尝试了相同的解决方案,结果相同。我什至尝试过不同版本的 MySql.Data.dll

错误堆栈:

System.Collections.Generic.KeyNotFoundException 未被用户代码处理 HResult=-2146232969 Message=给定的密钥不是 出现在字典中。来源=mscorlib 堆栈跟踪: 在 System.Collections.Generic.Dictionary`2.get_Item(TKey 键) 在 MySql.Data.MySqlClient.CharSetMap.GetChararcterSet(DBVersion 版本,字符串 CharSetName) 在 MySql.Data.MySqlClient.NativeDriver.GetFieldMetaData41() 在 MySql.Data.MySqlClient.NativeDriver.GetFieldMetaData() 在 MySql.Data.MySqlClient.NativeDriver.ReadColumnMetadata(Int32 计数) 在 MySql.Data.MySqlClient.MySqlDataReader.NextResult() 在 MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior 行为) 在 Panopticon.DataLayer.DatabaseHelper.RunExecuteDataReader(字符串 sql, C:\Users\Visar\Documents\Visual Studio 中的 MySqlParameter[] 参数) 2010\Projects\TestApp\TestApp\DataLayer\DatabaseHelper.cs:第 84 行 在 C:\Users\Visar\Documents\Visual Studio 中的 Panopticon._Default.Page_Load(Object sender, EventArgs e) 2010\Projects\TestApp\TestApp\Default.aspx.cs:第 16 行 在 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(对象发送者, 事件参数 e) 在 System.Web.UI.Control.OnLoad(EventArgs e) 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,布尔 includeStagesAfterAsyncPoint)
内部异常:

【问题讨论】:

  • 会重构你的助手以及从 .config 文件中读取并摆脱硬编码的值..
  • 你能发布错误堆栈吗?
  • 我在阅读 web.config 时当然认为有问题:(
  • 如果您从读取配置中获取值,这通常是一个好兆头。10 次中有 9 次出现问题在于参数以及参数类型以及 SQL 语句,但既然您'正在做选择 * 我不认为这是命令..
  • @Mark - 刚刚添加了错误堆栈。

标签: c# asp.net .net mysql


【解决方案1】:

用这个代码替换 - 你可以删除AddRange方法

 cmd.Parameters.Add(param);

并添加foreach处理

 foreach (var p in param)
        {
            cmd.Parameters.Add(p);
        }

DJ KRAZE 提到的最佳实践是使用AddWithValue method

链接:http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlparametercollection.addwithvalue.aspx

【讨论】:

  • 或 cmd.Parameters.AddWithValues(param) .Add 方法已被贬低
  • 是的,我知道,但第一次是发现问题,第二次用 AddWithValue 回答,谢谢 DJ KRAZE 的评论,我把你的回答加到我的回答中
  • 不是问题 Aghilas 你的回答已经足够好了 +1 我给了你我注意到的另一个问题是他将参数作为数组传递.. 如果其中一个参数不是,这也可能导致他潜在的问题已填充或为空,但您的解决方案应该足以让他继续前进
  • 这不是这里的问题。我不传递任何参数。即使我将方法更改为根本不包含参数,也会发生相同的错误。
  • 我确实尝试了你的建议......仍然是同样的问题:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
相关资源
最近更新 更多