InvalidCastException:无法将类型为“ System.DBNull”的对象转换为类型为“ System.Nullable`1 [System.Int32]”

时间:2019-06-10 05:59:00

标签: c# sql postgresql asp.net-core

我正在尝试从数据库执行存储过程。但是,我遇到一个例外:

  

InvalidCastException:无法将类型为'System.DBNull'的对象强制转换为   类型'System.Nullable`1 [System.Int32]'。

“ results.Add”行引发异常。

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"],
                    }
                );
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

使用Convert.IsDBNull()检查值是否为DBNull,然后使用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"],
    }
);

答案 1 :(得分:1)

摘自DBNull文档:

  

DBNull表示不存在的值,其中null表示不存在   对对象的引用。

要解决您的问题,

在更改值的类型之前先进行空检查,然后将其分配给变量

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"],
        });