2011-12-02 68 views
20

我在一段代碼中發現了一個奇怪的問題,即使它的參數與數據源中的記錄匹配,即使特定的SQL查詢沒有產生預期的輸出。我決定進入下面的測試表達式到立即窗口:爲什麼SqlParameter名稱/值構造函數將0視爲null?

new SqlParameter("Test", 0).Value 

這給了null結果,這讓我抓我的頭。看起來SqlParameter構造函數將零視爲空值。以下代碼會產生正確的結果:

SqlParameter testParam = new SqlParameter(); 
testParam.ParameterName = "Test"; 
testParam.Value = 0; 
// subsequent inspection shows that the Value property is still 0 

任何人都可以解釋此行爲嗎?它有點故意嗎?如果是這樣,它可能相當危險的......

+0

關於此主題的進一步閱讀:http://stackoverflow.com/questions/14224465/compiler-value-type-resolution-and-hardcoded-0-integer-values – RLH

回答

24

正如documentation該構造函數聲明:

當您指定的值參數的對象時,SqlDbType是從微軟的.NET Framework類型推斷的對象。

使用SqlParameter構造函數的過載指定整數參數值時請小心。由於此過載採用Object類型的值,因此,如下面的C#示例所示,當值爲零時,必須將積分值轉換爲Object類型。

Parameter = new SqlParameter("@pname", (object)0); 

如果不進行這種轉換,編譯器假定您要撥打SqlParameter(string, SqlDbType)構造函數重載。

你只是在調用與你的案例不同的構造函數。

這樣做的原因是,C#允許從整數字面0一個轉換到枚舉類型(這只是整數類型的下面),並且這隱式轉換導致(string, SqlDbType)構造成爲過載的分辨率更好的匹配比將int轉換爲object所需的裝箱轉換爲(string, object)構造函數所必需。

這永遠不會是一個問題,當你傳遞一個int可變,即使該變量的值是0(因爲它是不是零字面),或具有式int任何其他表達。如果您明確地將int轉換爲object(如上所示),也不會發生這種情況,因爲那樣只有一個匹配的過載。

+0

我有這個問題,並嘗試了不同的解決方案沒有工作:爲什麼提出的'參數=新的SqlParameter( 「@ PNAME」,Convert.ToInt32(0));'工作的時候'參數=新的SqlParameter( 「@ PNAME」,(INT),0);其中'我試過不? – mortb

+0

@mortb,你必須查閱該語言的規範,但我的猜測是,重載決議將在第二關心在第一種情況下的具體典型,但可能允許枚舉,因爲你還在通過文字的輸入'int'。 – Joey

+0

我已經找到了原因: http://stackoverflow.com/questions/3153841/strange-possibly-wrong-c-sharp-compiler-behavior-with-method-overloading-and 字面0將始終作爲評價匹配一個枚舉的類型,而其他數字不會。似乎有點晦澀...... – mortb

5

在傳遞/添加參數時使用類型化數據是很好的做法。

下面的方法可以完成如下任務:

對於字符串/ VARCHAR類型的數據:

SqlParameter pVarchar = new SqlParameter 
        { 
         ParameterName = "Test", 
         SqlDbType = System.Data.SqlDbType.VarChar, 
         Value = string.Empty, 
        }; 

對於int類型的數據:

SqlParameter pInt = new SqlParameter 
        { 
         ParameterName = "Test", 
         SqlDbType = System.Data.SqlDbType.Int, 
         Value = 0, 
        }; 

您可以更改的值根據您使用的數據,您可以使用SqlDbType

+0

雖然通常有幫助,但這在技術上不是問題的答案。因此它應該是一個評論。 – Joey

+2

@Joey,是的,你說得對,謝謝你的時間。 –

相關問題