Option Strict On和DBNull.Value

时间:2016-11-03 19:08:14

标签: vb.net visual-studio-2015 sql-server-2016

我已经开始将我的应用程序转换为使用Option Strict On。我一直在做CStr,Ctype等,而且进展顺利。

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

然后我点了这个。 txtEarningsTerminated.DateValue 是一个自定义屏蔽文本框。如果它的价值是什么,我不想在数据库中存储任何东西。但是,它说明了

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

当我将DBNull.Value更改为""或者没有,错误就消失了。但是作为Nothing,它在运行时声明

期间失败
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?

下不会产生错误

3 个答案:

答案 0 :(得分: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

然后使用它而不是“内联If方法”

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

答案 1 :(得分:0)

以下是一种方法(假设您在数据库中使用存储过程):

  1. 在您正在调用的存储过程中,将日期输入参数设置为null,使其成为可选字段,默认值为null(@terminate DATETIME = NULL)。
  2. 这样,如果您不在程序调用中包含该参数,则该过程不会失败。

    1. 将日期字段的默认值设置为DateTime.MinValue,使其始终具有某个值。然后,您可以测试它是否等于DateTime.MinValue以外的日期。如果它是有效的日期值,请添加该行以将日期参数包括在过程调用中。如果它等于DateTime.MinValue,请不要将参数添加到调用中。

答案 2 :(得分:0)

所以答案显而易见并且错误。我只需要在Ctype对象中包含DBNull.Value

var foo = function () {
        var a = {
            "abc":"value1"
            "bcd":"value2"
        }
        return a;
    };

然后代码编译得很好。