2011-08-31 47 views
0

所以我使用了這個舊的代碼,它爲數據庫調用運行簡單的ExecuteNonQuery命令。我正在使用DbConnection,DbTransaction和其他System.Data.Common命令。這個數據庫類的執行查詢函數有什麼問題嗎?

只要我在項目的某些部分使用該函數,似乎會得到很多空引用錯誤,儘管在其他部分看起來很好。我認爲它與手動打開連接或調用它有一些問題有關,但是我想知道函數本身是否原本設計得很差(不應該有辦法以它被調用的方式修復任何問題嗎?)

我覺得涉及到事務時,這些空引用錯誤會出現得更多,我認爲我得到的錯誤是空例外「_command = _db.GetStoredProcCommand(storedProcedure);」裏面有以下功能。但該存儲過程確實存在,所以它沒有任何意義。

public List<OutputParameter> execute(String storedProcedure, StoredProcedureParameter[] sqlParameters) 
{ 
    try 
    { 
     List<OutputParameter> outputParameters = new List<OutputParameter>(); 
     _command = _db.GetStoredProcCommand(storedProcedure); 

    for (int x = 0; x < sqlParameters.GetLength(0); x++) 
    { 
     if (sqlParameters[x] != null) 
     { 
     StoredProcedureParameter sqlParameter = sqlParameters[x]; 
     String param = sqlParameter.ParameterName; 

     DbType dbType = sqlParameter.DbType; 
     object value = sqlParameter.Value; 
     if (sqlParameter.IsOutputParam) 
     { 
      _db.AddOutParameter(_command, param, dbType, 32); 

      OutputParameter outputParameter = new OutputParameter(param); 
      outputParameters.Add(outputParameter); 
     } 
     else 
      _db.AddInParameter(_command, param, dbType, value); 
     } 
    } 
    if (_transaction == null) 
     _db.ExecuteNonQuery(_command); 
    else 
     _db.ExecuteNonQuery(_command, _transaction); 

    foreach (OutputParameter op in outputParameters) 
    { 
     op.ParameterValue = _db.GetParameterValue(_command, op.ParameterName); 
    } 

    return outputParameters; 
    } 
    catch (SqlException sqle) 
    { 
    throw new DataAccessException(sqle.ToString()); 
    } 
    catch (Exception e) 
    { 
    throw new DataAccessException(e.ToString()); 
    } 
} 
+0

'_command'定義在哪裏?還有哪些地方被訪問? – Oded

+0

private DbCommand _command = null; ---這不是呃,除了通過這個GetStoredProcCommand的東西來啓動。它可以在QueryDatabase()等其他函數中訪問,它可以返回結果而不是像execute()那樣執行。 – Dexter

+0

並且您訪問了多少個地方?你在代碼中的許多地方使用'execute'嗎? – Oded

回答

2

您的_command變量似乎是一個字段,並且是這樣一個共享成員。

因爲這樣你的代碼是很容易容易出現多線程問題(如果兩個函數用不同的存儲過程調用這個類,會發生什麼?)。

A Command也應該被關閉並妥善處置,這不會在您的代碼中發生,並非明確無誤。

+0

我認爲asp.net和網站通常非常線性的事實,使得它沒有多線程,就像PHP沒有多線程,除非你使用POSIX函數。讓我猜,我錯了?那麼我應該如何編碼來解決這個問題呢?應該命令不是一個私人變量,更多的是使用「使用」的局部變量? – Dexter

+0

@Dexter - 向asp.net添加線程非常容易,因此假設您的代碼只能在單個完全隔離的線程上運行,可能會帶來麻煩。你用一個'using'語句來敲打頭部局部變量。 – Oded

+0

雖然沒有解決問題。也許別的東西是空的,比如_conn或_command。其中在數據訪問類構造創建中初始化: public DataAccess() { _db = DatabaseFactory.CreateDatabase(); _conn = _db.CreateConnection(); } – Dexter

1

如果您在行_command = _db.GetStoredProcCommand(storedProcedure);中收到空引用異常,那麼唯一可以爲空的是_db。 storedProcedure只是一個參數,_command可以很好地爲空而沒有問題。

由於您實際上並沒有在代碼中做任何事情來確保_db存在且有效,打開等,那麼這很可能是問題所在。

+0

這裏的問題,當我有if(da.getConnectionState()== ConnectionState.Closed)da.openConnection();在代碼的某些領域,它也造成了錯誤。所以我刪除了任何打開的連接,因爲有人告訴我手動打開連接是錯誤的,因爲它是自動管理的。它解決了很多問題(還有一些代碼留在了這裏)。當類初始化時_db被初始化。 _db = DatabaseFactory.CreateDatabase(); – Dexter