web-dev-qa-db-ja.com

DataReader.GetString()でタイプ「System.Int32」のオブジェクトをタイプ「System.String」にキャストできません

データベースからacomboboxにデータを追加しようとしていました。

        try
        {
            SqlCeCommand com = new SqlCeCommand("select * from Category_Master", con);
            SqlCeDataReader dr = com.ExecuteReader();
            while(dr.Read()){
                string name = dr.GetString(1);
                cmbProductCategory.Items.Add(name);
            }
        }
        catch(Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

次の例外が発生します。

タイプ「System.Int32」のオブジェクトをタイプ「System.String」にキャストできません

ここで何が欠けていますか?

8
Kamal

明らかに、あなたの列はタイプstringを持っていません。どうやらintです。だから使用:

dr.getInt32(1).ToString()

あるいは

dr.GetValue(1).ToString()

これは、データベースの変更を入力するのに、より粗いはずです。

ある種の一般的なアドバイスとして、私は少なくとも従うようにしています:

  • 必要なものだけを選択してください。これには主にパフォーマンス上の理由がありますand列名を明示的に指定する必要があるため、スキーマに互換性のない変更を加えると、少なくとも実用的なエラーが発生します。
  • 名前を使用してフィールドにアクセスします。

    dr.GetGuid(dr.GetOrdinal("id"))
    

    このようなことは、拡張メソッドによってもうまく解決できます:

    public T GetFieldValue<T>(this DbDataReader reader, string columnName)
    {
        return reader.GetFieldValue<T>(reader.GetOrdinal(columnName));
    }
    

補足:スタックトレースを含めること(または、少なくともコードのどの行から例外が発生するかを伝えること)は、他のユーザーを助けようとするときに役立ちます。あなたが野生から見ることができるように、犯人は何であったかを推測します。私の推測では、スタックトレースは次のようになります。

SqlDataReader.GetString
YourCode.YourMethod

そしてGetStringは多かれ少なかれこのように見えます:

public string GetString(int index)
{
    return (string) GetValue(index);
}
19
Joey

列の型がintではないようです。このようなことを回避するには、インデックスの代わりに列名を使用できます。

try
{
    SqlCeCommand com = new SqlCeCommand("select * from Category_Master", con);
    SqlCeDataReader dr = com.ExecuteReader();
    while(dr.Read()){
        string name = dr["yourColumnName"].ToString();
        cmbProductCategory.Items.Add(name);
    }
}
catch(Exception ex)
{
    System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
1
Koen

わかった、わかった。その解決...

これがコードです。

        try
        {
            SqlCeCommand com = new SqlCeCommand("select CategoryName from Category_Master", con);
            SqlCeDataReader dr = com.ExecuteReader();
            while(dr.Read()){
                string name = dr.GetString(0);
                cmbProductCategory.Items.Add(name);
            }
        }
        catch(Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

Sqlcommandを単一の値に変更し、dr.getstring()の列番号を0に変更しました。助けてくれてありがとう。プロジェクトの途中なので、もっと期待します。

0
Kamal