2016-11-03 2 views
1

Я начал конвертировать мое приложение для использования опции Strict On. Я делаю CStr, Ctype и т. Д., И все идет хорошо.Опция 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.

Как это сделать, чтобы не создавать ошибки в опции Strict On?

+0

попробуйте установить значение null по умолчанию в хранимой процедуре для этого параметра. – McNets

+0

'DbNull' - это не то же самое, что' Nothing'. Не знаю, что такое 'txtEarningsTerminated', так как оно имеет свойство' DateValue', но я сомневаюсь, что оно Nullable – Plutonix

+0

txtEarningsTerminated.DateValue - это дата? – Kayot

ответ

0

Таким образом, ответ был очевиден, и в ошибке. Мне просто пришлось заключить DBNull.Значение в объекте Ctype

CType(DBNull.Value, Object) 

И тогда код будет компилироваться просто отлично.

0

Вот один из способов сделать это (при условии, что вы с помощью хранимых процедур в базе данных):

  1. В хранимой процедуре вы звоните, установите параметр ввода даты равным NULL, что делает его необязательное поле со значением по умолчанию 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-уже /). (И прелесть в том, чтобы сделать вашу программу опцией Strict On-compliant.) –

2

Причина в том, что оператор If(condition, executeAndReturnIfTrue, executeAndReturnIfFalse) ожидает, что оба true и false выражения будут возвращать тот же тип.
В вашем случае вы возвращаете 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 автоматически решить этот тип данных для значения, которое может привести в разные проблемы. Например, каждый раз, когда вы запускаете тот же запрос с разными значениями, ваш план запроса будет перекомпилирован каждый раз при изменении значения.

Вы можете создать метод расширения для 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()' не функция, а оператор. –

Смежные вопросы