簡體   English   中英

無法將對象從DBNull強制轉換為其他類型。 讀取器讀取空值時出錯

[英]Object cannot be cast from DBNull to other types. Error when a null value is read by the Reader

int topID = 0;
string TopIDQuery = "Select TopID from tbl_Organisation where OrganisationID=@OrgID";

paramet[0] = new MySqlParameter("@OrgID", MySqlDbType.Int32);
paramet[0].Value = OrgID;

reader = server.ExecuteReader(CommandType.Text, TopIDQuery, paramet);

while (reader.Read())
{
    topID = Convert.ToInt32(reader["TopID"]);
}

reader.Close();

我正在從表中讀取topID ,當TopID為null時我想將topID為0,但由於它為null,因此拋出錯誤,當topID為null時如何處理此錯誤

將您的閱讀代碼更改為:

while (reader.Read())
{
    if(reader.IsDBNull(reader.GetOrdinal("TopID")))
       topID = 0;
    else
       topID = Convert.ToInt32(reader["TopID"]);
}

在嘗試轉換列之前,在閱讀器上調用IsDBNull()以檢查列:

   using (reader = server.ExecuteReader(CommandType.Text, TopIDQuery, paramet))
   {
       while (reader.Read())
       {
           var column = reader.GetOrdinal("TopID");

           if (!reader.IsDBNull(column))
              topID = Convert.ToInt32(reader[column]);
           }
       }
   }

或者,與DBNull.Value進行比較:

   var value = reader["TopID"];

   if (value != DBNull.Value)
   {
       topID = Convert.ToInt32(value);
   }

使用測試:

int columnNr = reader.GetOrdinal("TopID");
if (!reader.IsDBNull(columnNr)) {
    topID =  reader.GetInt32(columnNr);
}

問題是你試圖用null設置int,而不是在read中。 如果您嘗試放入的值為null,則可以設置備用值:

    topID = Convert.ToInt32(reader["TopID"]) ?? 0;

另一種方法是你可以通過初始化topID來使用可空整數,如下所示:

int? topID = 0

但是這樣做仍然需要在其他地方檢查null,以及其他一些必須處理的東西,所以我建議在我的第一個顯示的值集上使用雙重問號。

這是我們在任何注冊表單的頁面加載時自動生成來自ms訪問數據庫的任何id的代碼

void Number()
{
    con.Open();
    int id;
    cmd = new OleDbCommand("select max(ID) from Entry", con);
    string value = (cmd.ExecuteScalar().ToString());
    string max;
    if (value != null)
    {      
        max = "0"+value;
        id = Convert.ToInt32(max);
        lblNumber.Text = "Acronym of Reg form like for Emp for Employee" 
                        + Convert.ToString((id + 1));

    }
    con.Close();
}

在閱讀器上使用通用擴展方法(參見類似的SO問題

topID = reader.GetFieldValueOrDefaultIfDBNull<Int32>("TopID");

在您的閱讀器類(MySql,Sql,Oracle等)上實現此擴展方法

public static T GetFieldValueOrDefaultIfDBNull<T>(this SqlDataReader reader, string indexName)
{
    if (reader.IsDBNull(reader.GetOrdinal(indexName)))
    {
        return default(T); // returns the default value for the type
    }
    else
    {
        return reader.GetFieldValue<T>(reader.GetOrdinal(indexName));
    }
}

在嘗試檢索之前,您需要檢查值是否為DBNull。 此外,我建議在Convert.ToInt32()使用GetInt32() ,因為已經聲明GetInt32()內部優化可能會改變比使用Convert.ToInt32()更快的地方。 我很久以前就學到了這一點,並且沒有一篇參考文章可供您查看。 當我得知這個GetInt32()在內部使用Convert.ToInt32()

while(reader.Read()) {
    int TopIDIndex = reader.GetOrdinal("TopID");
    topID = reader.IsDBNull(TopIDIndex)
        ? 0
        : reader.GetInt32(TopIDIndex);
}

我喜歡使用DataTable而不是DataReader 我討厭重復的樣板,所以我在DataRow類中添加了一些擴展方法來封裝downcast邏輯並使代碼更具可讀性:

DataTable dt = ExecStoredProcedure() ;
foreach ( DataRow dr in dt )
{
  int       id            = dr.CastAsInt("id") ;
  dateTime? dtLastUpdated = dr.CastAsDateTimeNullable("last_update_date") ;
  int?      col3          = dr.CastASIntNullable(3) ;
}

這里是將一個列值從DataRow向下轉換為int / int?

#region downcast to int

public static int CastAsInt( this DataRow row , int index )
{
    return toInt( row[index] ) ;
}
public static int CastAsInt( this DataRow row , string columnName )
{
    return toInt( row[columnName] ) ;
}

public static int? CastAsIntNullable( this DataRow row , int index )
{
    return toIntNullable( row[index] );
}
public static int? CastAsIntNullable( this DataRow row , string columnName )
{
    return toIntNullable( row[columnName] ) ;
}

#region conversion helpers

private static int toInt( object o )
{
    int value = (int)o;
    return value;
}

private static int? toIntNullable( object o )
{
    bool hasValue = !( o is DBNull );
    int? value    = ( hasValue ? (int?) o : (int?) null ) ;
    return value;
}

#endregion conversion helpers

#endregion downcast to int

我確定從DataReader掛起類似的擴展方法會相當簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM