2

I am trying to execute a stored procedure from DB. However, I am getting an exception:

InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.Nullable`1[System.Int32]'.

Exception is thrown by "results.Add" line.

var result = new List<GetActiveUserPackagesForOpenBillingPeriodResult> ();

using (var conn = new NpgsqlConnection ("Host=localhost;Port=xxx;Database=xxx;Username=postgres;Password=xxx;TrustServerCertificate=true;ApplicationName=xxx;")) {
    using (var cmd = new NpgsqlCommand ("\"GetActiveUserPackagesForOpenBillingPeriod\"", conn)) {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue ("somedate", DateTime.Today);
        conn.Open ();

        var reader = cmd.ExecuteReader ();

        string x = DBNull.Value.Equals (reader) ? " " : reader.ToString ();

        if (x != null) 
        {
            while (reader.Read ()) {

                result.Add (
                    new GetActiveUserPackagesForOpenBillingPeriodResult {
                        Amount = (decimal) reader["Amount"],
                            AcceptanceActID = (int?) reader["AcceptanceActID"],
                            PackageID = (int) reader["PackageID"],
                            UserID = (int) reader["UserID"],
                            AccountID = (int) reader["AccountID"],
                            HasChangedPackage = (bool) reader["HasChangedPackage"],
                    }
                );
            }
        }
    }
}
cdev
  • 5,043
  • 2
  • 33
  • 32
Guga Todua
  • 462
  • 2
  • 11
  • 27

2 Answers2

9

From DBNull Documentation:

DBNull represents a nonexistent value, where null denotes absence of reference to the object.

To fix your issue,

Null check before changing value's type and then assign it to the variable

result.Add (
     new GetActiveUserPackagesForOpenBillingPeriodResult {
     Amount = (decimal) reader["Amount"],
     AcceptanceActID =  Convert.IsDBNull(reader["AcceptanceActID"]) ? null : (int?) reader["AcceptanceActID"],
     PackageID = (int) reader["PackageID"],
     UserID = (int) reader["UserID"],
     AccountID = (int) reader["AccountID"],
     HasChangedPackage = (bool) reader["HasChangedPackage"],
        });
Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44
2

Use Convert.IsDBNull() to check value is DBNull and then use value

result.Add (
    new GetActiveUserPackagesForOpenBillingPeriodResult {
        Amount = (decimal) reader["Amount"],
            AcceptanceActID = !Convert.IsDBNull(reader["AcceptanceActID"]) ? (int?) reader["AcceptanceActID"] :  null,
            PackageID = (int) reader["PackageID"],
            UserID = (int) reader["UserID"],
            AccountID = (int) reader["AccountID"],
            HasChangedPackage = (bool) reader["HasChangedPackage"],
    }
);
cdev
  • 5,043
  • 2
  • 33
  • 32