0

I have a GetProduct method that is supposed to return the product code, description, and price in a MessageBox. Currently, I am only able to display the word "Price" with a title on the box "IndexOutOfBoundsException" when it actually finds a product matching the code. If not, it displays that it is not found.

Here is the code:

        public static Product GetProduct(string code)
    {
        SqlConnection connection = Connection.GetConnection();

        string select = @"SELECT ProductCode, Description, UnitPrice FROM Products WHERE ProductCode = @ProductCode";

        SqlCommand selectCommand = new SqlCommand(select, connection);


        SqlParameter pCode = new SqlParameter();
        pCode.ParameterName = "@ProductCode";
        pCode.Value = product.Code;
        SqlParameter pDesc = new SqlParameter();
        pDesc.ParameterName = "@Description";
        pDesc.Value = product.Description;
        SqlParameter pPrice = new SqlParameter();
        pPrice.ParameterName = "@UnitPrice";
        pPrice.Value = product.Price;

        selectCommand.Parameters.AddWithValue("@ProductCode", code);

        try
        {
            connection.Open();

            SqlDataReader prodReader = selectCommand.ExecuteReader(CommandBehavior.SingleRow);

            if (prodReader.Read())
            {
                product.Code = prodReader["ProductCode"].ToString(); ;
                product.Description = prodReader["Description"].ToString();
                product.Price = ((decimal)prodReader["Price"]);

                return product;
            }
            else
            {
                return null;
            }
        }
        catch (SqlException ex)
        {
            throw ex;
        }
        finally
        {
            connection.Close();
        }

    }
GSto
  • 1
  • 2

1 Answers1

0

You have a field named UnitPrice while the reader's string indexer used is named Price. This produces the IndexOutOfRangeException.
While this is a common typo it is interesting to know why this happens.

Internally the string indexer for the data reader contains this code

override public object this[string name] {
    get {
        return GetValue(GetOrdinal(name));
    }
}

As you can see it uses the GetOrdinal public method to retrieve the index of the field from its name. However, if the name passed is not found the call to GetOrdinal returns -1 and of course this is not a valid index on the underlying fields array going from 0 to FieldCount - 1

Steve
  • 213,761
  • 22
  • 232
  • 286