Pregunta

why would this work

int collectionCharge = (int)cmdCheck.ExecuteScalar();

but this produces an exception

double collectionCharge = (double)cmdCheck.ExecuteScalar();

System.InvalidCastException: Specified cast is not valid.

why would it not be valid?

EDIT I am trying to simply return a single result from a query, that gets the price of some freight. So I can't turn this into an int because it must have decimals, hence trying to cast to a double. I am still learning asp.net so if there's a better way to achieve this, please do point me in the right direction :)

EDIT 2 the full code with SQL...

using (SqlCommand cmdCheck = new SqlCommand("SELECT FREIGHT_PRICE FROM FREIGHT_QUOTER_BELNL_NEW WHERE CUSTOMER_NO = @CUSTOMER_NO AND COUNTRY = @COUNTRY AND ROUND(WEIGHT_FROM,0) < @WEIGHT AND ROUND(WEIGHT_TO,0) >= @WEIGHT AND SHIPVIA = '48';", connection))
                {
                    double collectionCharge = (double)cmdCheck.ExecuteScalar();
                    FreightAmount = collectionCharge;
                }
¿Fue útil?

Solución 3

With thanks to @DJKRAZE.

I updated my query to SELECT CASE(FREIGHT_PRICE AS FLOAT) which now works with the (double) cast.

double collectionCharge = (double)cmdCheck.ExecuteScalar();

Otros consejos

The problem here is that ExecuteScalar is returning an int which is boxed into an object. In order to convert to a double you must first unbox to an int then convert to a double

double collectionCharge = (double)(int)cmdCheck.ExecuteScalar();

Use the Convert.ToXXX to avoid invalid cast exceptions.

I.E

collectionCharge=Convert.ToDouble(cmdCheck.ExecuteScalar());

As it appears that ExecuteScalar returns an Object so the code:

double collectionCharge = (double)cmdCheck.ExecuteScalar();

Could still fail

After reading all answers, I had a case of receiving the Decimal values indeed, and the solution was easy! I just declared the function as string and received the Decimal value as string!

public static string Sals_AccountExpensesGetSums(int accountID)

{

SqlParameterHelper sph = new 
SqlParameterHelper(ConnectionString.GetWriteConnectionString(), 
"sals_AccountExpenses_GetAllSums", 1);

sph.DefineSqlParameter("@AccountID", SqlDbType.Int, ParameterDirection.Input, accountID);


string res = sph.ExecuteScalar().ToString();

return res;
}

and in the business layer i changed the result to double!

public static decimal GetAccountExpensesSums(int accountId)
{
string res = "";
decimal sums = 0;

res = DBAccount.Sals_AccountExpensesGetSums(accountId);

// check so we will not have exception 
if ( res != "")
sums = Convert.ToDecimal(res);

return sums;

}

and the result was perfect as needed: 889678.70

I would recommend using this code:

object o = c.ExecuteScalar();
     if (o != null)
     {
         int x = Int32.Parse(o.ToString());      
     }

This does two things. First it makes sure that your c.ExecuteScalar() isn't returning null If it did so and you tried to cast, you'd have problems.

Second, it makes casting much simpler because it can be applied to pretty much all cases when reading from a query.

The object becomes a string. If you want it as a string, you're done. If you want it as a boolean, check to see if that string.Equals("true") If you want it as an int, Int32.Parse(string); if you want it as a long, Int64.Parse(string);

Basically, you won't have to worry about fully understanding overloading/explicit conversion.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top