2

私は問題に行き詰まっており、WTF が起こっているという考えが 1 つもありません。Web サービスを使用して MySQL データベースと通信する必要がある C# Web アプリケーションがあります。メソッドを使用してデータを挿入できますが、何か (ExecuteReader または ExecuteScalar) を読み込もうとすると、次の非常に奇妙なメッセージで失敗します。

指定されたキーはディクショナリに存在しませんでした。

これで、Web サービスはこのクラスを使用してデータベースと通信します。

 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 StackTrace: 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 カウント) でPanopticon.DataLayer.DatabaseHelper.RunExecuteDataReader(String sql,
内部例外:

4

1 に答える 1

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

于 2012-10-09T19:10:16.080 に答える