0

When I try to get an Integer from my SQLite db I can only get it working by reading it as a string and then run int.Parse on it. Is this right, I read something about this having to do with ExeculeScalar possibly giving back null?

Here is my current code SendSQLExecScalar() sends the command string etc. and return an object

public object SendSQLExecScalar(string C)
{
        OpenConnection();
        SQLiteCommand SQLCommand = new SQLiteCommand(C, DbConnection);

        try
        {
            object Output = SQLCommand.ExecuteScalar();
            CloseConnection();
            return Output;
        }
        catch (Exception X)
        {
            MessageBox.Show(X.Message);
            return null;
        }
}

And:

int ID = int.Parse(SendSQLExecScalar(C).ToString());

EDIT :

Specified cast is not valid.

public static int GetImageID(string Path)
{
     string C = "SELECT ID FROM Images WHERE Path LIKE '" + Path + "' LIMIT 1";

     return ConvertFromDBVal<int>(SendSQLExecScalar(C));
}

public static T ConvertFromDBVal<T>(object obj)
{
      if (obj == null || obj == DBNull.Value)
      {
          return default(T);
      }
      else
      {
          return (T)obj;  //breaks here saying this cast is invalid
      }
}
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
Unhek
  • 93
  • 1
  • 9

3 Answers3

0

I read something about this having to do with execuleScalar possibly giving back null?

Yes, if there is no data that your sql query returns, ExecuteScalar returns null reference.

If you are 100% sure the return value on the first column of the first row is already int, you can just cast it like;

int ID = (int)SendSQLExecScalar(C);

To prevent null cases on this method, I almost always uses rein's generic method as;

public static T ConvertFromDBVal<T>(object obj)
{
    if (obj == null || obj == DBNull.Value)
    {
        return default(T); // returns the default value for the type
    }
    else
    {
        return (T)obj;
    }
}
Community
  • 1
  • 1
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • in my case obj will output as a number like 5 if not null, and then break saying the cast of (int)5 is not valid. – Unhek Jul 26 '15 at 11:46
  • @Unhek You will use this generic method for the result of the `SendSQLExecScalar` method. And `(int)5` is valid. What is your code exactly that shows invalid cast? – Soner Gönül Jul 26 '15 at 12:03
  • ' public static int GetImageID(string Path) { string C = "SELECT ID FROM Images WHERE Path LIKE '" + Path + "' LIMIT 1"; return ConvertFromDBVal(SendSQLExecScalar(C)); } public static T ConvertFromDBVal(object obj) { if (obj == null || obj == DBNull.Value) { return default(T); } else { return (T)obj; } }' – Unhek Aug 01 '15 at 17:14
  • @Unhek I tried your work and it works as I expected. – Soner Gönül Aug 01 '15 at 17:21
  • ook, got it working using (int)(long)SendSQLExecScalar(C); looks like sqlite is return a long for some reason. – Unhek Aug 01 '15 at 17:32
  • @Unhek Are you sure your `SendSQLExecScalar(C)` really returns `5`? – Soner Gönül Aug 01 '15 at 17:43
  • Well not only five, but it returns an integral, but it returns a long which it wont cast to int. – Unhek Aug 04 '15 at 09:39
0

Use TryParse instead of Parse, this allows you to test whether something is parseable.

If you use int.Parse() with an invalid int, you'll get an exception while in the TryParse, it returns a boolean letting you know whether the parse succeeded or not.

In short use Parse if you are sure the value will be valid; otherwise use TryParse.

int number = int.Parse(someString);    

int number;
int.TryParse(someString, out number);
Vinoth
  • 2,419
  • 2
  • 19
  • 34
0
(int)(long)SendSQLExecScalar(C);

Solved with this, looks Like SQLite integer will return a long object which I needed to unpack before casting it to an int.

Unhek
  • 93
  • 1
  • 9