2016-11-03 41 views
1

我已經開始將我的應用程序轉換爲使用Option Strict On。我一直在做CStr,Ctype等,並且一切順利。Option Strict On和DBNull.Value

SQLCommand.Parameters.AddWithValue("@TERMINATE", If(IsNothing(txtEarningsTerminated.DateValue), DBNull.Value, txtEarningsTerminated.DateValue)) 

然後我打這個。 txtEarningsTerminated.DateValue是一個自定義屏蔽的文本框。當它的值是Nothing時,我不想在數據庫中存儲任何內容。但是,它聲明

Cannot infer a common type, and Option Strict On does not allow 'Object' to be assumed. 

當我將DBNull.Value更改爲「」或什麼也沒有,錯誤消失。然而,由於沒有,它在運行時陳述失敗

The parameterized query '(@CONTROL int,@CLIENTCODE nvarchar(10),@NoBill int,@TERMINATE nv' expects the parameter '@TERMINATE', which was not supplied. 

我想要在數據庫中的NULL。此值可以是日期,然後變爲NULL。

如何翻譯此以免在Option Strict On下產生錯誤?

+0

嘗試在您的存儲過程中爲此參數設置默認的空值。 – McNets

+0

'DbNull'與'Nothing'不是一回事。不知道'txtEarningsTerminated'是什麼,因爲它有'DateValue'屬性,但我懷疑它是可空的 – Plutonix

+0

txtEarningsTerminated.DateValue是一個日期? – Kayot

回答

0

因此,答案是顯而易見的,並在錯誤。我只需要裝入DBNull。Ctype對象中的值

CType(DBNull.Value, Object) 

然後代碼會編譯得很好。

0

這裏有一個辦法做到這一點(假設你使用你的數據庫的存儲過程):

  1. 在你調用存儲過程,日期輸入參數設置爲等於空,使之成爲一項可選字段的默認值爲null(@terminate DATETIME = NULL)。

這樣,如果在過程調用中不包含該參數,則該過程不會失敗。

  1. 將日期字段的默認值設置爲DateTime.MinValue,以便始終具有某個值。然後您可以測試它是否等於DateTime.MinValue以外的日期。如果它是有效的日期值,則添加該行以將日期參數包括到過程調用中。如果它等於DateTime.MinValue,則不要將該參數添加到該調用中。
+0

SQL語句非常小,無法轉化爲存儲過程。在C#中,我可以使用null,它可以工作。我想知道爲什麼我不能在這裏做到這一點? – Kayot

+0

@Kayot'AddWithValue'可以給出問題:[我們可以停止使用AddWithValue()了嗎?](http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using- addwithvalue-已經/)。 (並且讓您的程序選項嚴格遵從標準。) –

2

的原因是因爲運營商If(condition, executeAndReturnIfTrue, executeAndReturnIfFalse)預計這兩個truefalse表達式將返回相同的類型。
如果結果爲假,則返回DbNull類型(如果爲true)和String(或其他未提及的其他類型)。

如果更明確地創建SqlParameter,那麼你可以使用另一個方法:

Dim value As Object = Nothing 
If txtEarningsTerminated.DateValue Is Nothing Then 
    value = DbNull.Value 
Else 
    value = xtEarningsTerminated.DateValue 
End If 

Dim param As SqlParameter = New SqlParameter With 
{ 
    .ParameterName = "@TERMINATE", 
    .SqlDbType = SqlDbType.VarChar, 'Or use your correct type 
    .Value = value 
} 

由於使用AddWithValue將迫使ADO.NET自動決定的SQL類型爲你的價值在評論中提到的,這可能會導致在不同的問題。例如,每次使用不同的值運行相同的查詢時,每次更改值時都會重新編譯查詢計劃。

可以爲string

Public Module ExtensionsModule 
    Public Function DbNullIfNothing(this As String) As Object 
     If this Is Nothing Then Return DBNull.Value 
     Return this 
    End Function 
End Module 

創建擴展方法,那麼用它代替你的「內聯如果方法」

Dim value As String = Nothing 
Dim param As SqlParameter = New SqlParameter With 
{ 
    .ParameterName = "@TERMINATE", 
    .SqlDbType = SqlDbType.VarChar, 
    .Value = value.DbNullIfNothing() 
} 
+0

只是一點兒瑣事,'If()'不是一個函數,而是一個操作符。 –

相關問題