Matheus Saviczki
Matheus Saviczki

Reputation: 63

Calling GetString on a SqlDataReader is giving me an InvalidCastException

I am looking to move data in a arraylist for a Listbox, but it is giving error. Error :

An unhandled exception of type 'System.InvalidCastException' occurred in System.Data.dll Additional information: You can not convert an object of type 'System.Int32' on type 'System.String'.

This happens on line: fill_arry[i] = objReader.GetString(1);

Code:

public void Fill_List(ArrayList fill_arry)
{
    SqlDataReader objReader;
    SqlCommand objcmd =null;

    int i = 0;

    vsql = "SELECT [NOME] As Identificador,[RGP],[NOME],[ENDERECO],[CIDADE],[ESTADO],[TELEFONE],[CELULAR] FROM pescador";

    if (this.Conectar())
    {
        try
        {
            objcmd = new SqlCommand(vsql, objCon);
            objReader = objcmd.ExecuteReader();

            while (objReader.Read())
            {
                fill_arry[i] = objReader.GetString(1);
            }
        }
        catch (SqlException erro)
        {
            throw erro;
        }
        finally
        {
            this.Desconectar();
        }
    }
}

Upvotes: 0

Views: 1654

Answers (2)

sstan
sstan

Reputation: 36483

Using a List<T> instead of an ArrayList is, as others are saying, better practice. But it isn't the reason for your error.

The cause of your error is this: objReader.GetString(1).

This is trying to fetch the value of the column RPG as if it was a string, when in fact, according to the error, it is an int.

To get rid of the error, but still get the value as a string, just change it to objReader.GetInt32(1).ToString().

EDIT: Well, apparently, you want [NOME], not [RGP] :)

It would have been nice to specify that. The indexes on SqlDataReader start at 0. so to get NOME, you need to fetch it as:

objReader.GetString(0);

Or, better yet, if you want to avoid getting the indexes wrong, why not do it this way:

(string)objReader["Identificador"]; // named parameter instead of an index, yay!

Upvotes: 3

Max
Max

Reputation: 13338

Edit:

No, I need to get the NOME

so [NOME] is the desired field, change:

fill_arry.Add(objReader.GetString(1));

To:

fill_arry.Add(objReader.GetString(0));

Note: As sstan wrote down in his answer, you are retrieving the [RGP] column value, is this what you want? Since it is an int you would have to convert. If you want to get [NOME] than change 1 to 0, since the index starts at zero.

Using a normal List is preferred over the old ArrayList. Casting isn't necessary using a List instead of an ArrayList. The ArrayList stores the object references. You would end up with a function like:

public void Fill_List(List<string> fill_arry)
{
    SqlDataReader objReader;
    SqlCommand objcmd =null;

    int i = 0;

    vsql = "SELECT [NOME] As Identificador,[RGP],[NOME],[ENDERECO],[CIDADE],[ESTADO],[TELEFONE],[CELULAR] FROM pescador";

    if (this.Conectar())
    {
        try
        {
            objcmd = new SqlCommand(vsql, objCon);
            objReader = objcmd.ExecuteReader();

            while (objReader.Read())
            {
                //The value is added to List<string> fill_arry here.
                fill_arry.Add(objReader.GetString(1));
            }
        }
        catch (SqlException erro)
        {
            throw erro;
        }
        finally
        {
            this.Desconectar();
        }
    }
}

Method should be called something like this:

List<string> strList = new List<string>();
Fill_List(strList);

Refer to below answer, to know why you shouldn't use an ArrayList, instead of a List.

A short quote from the answer:

ArrayList belongs to the days that C# didn't have generics. It's deprecated in favor of List. You shouldn't use ArrayList in new code that targets .NET >= 2.0 unless you have to interface with an old API that uses it.

SO answer

Upvotes: 3

Related Questions