2016-11-03 40 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()'不是一个函数,而是一个操作符。 –

相关问题