Установка параметра в DBNull.Value с использованием троичного синтаксиса дает ошибку?

У меня есть следующий фрагмент кода для установки параметра, который будет использоваться в операторе INSERT для установки столбца VARCHAR в базе данных SQL Server. Мой объект-значение (с именем ilo) имеет свойство с именем Description, которое инициализируется значением String.Empty, а затем либо получает какое-либо значение, считываемое из XML, либо, если этот элемент XML пуст, он просто остается как String.Empty.

Поэтому при вставке в базу данных, если для свойства все еще задано значение String.Empty, я бы хотел, чтобы оно вставляло нулевое значение.

database.AddInParameter(cmd, "@description", DbType.String, 
                           (ilo.Description.Equals(string.Empty)) ?
                            DBNull.Value :
                            ilo.Description);

Таким образом, в основном я говорю, что если ilo.Description равен string.empty, установите для параметра значение DBNull.Value, в противном случае установите для него значение ilo.Description.

Это дает следующую ошибку в Visual Studio ...

Ошибка 141 Тип условного выражения не может быть определен, поскольку не существует неявного преобразования между «System.DBNull». и «строка»;

Зачем?

Любопытно, что я могу сделать следующее без ошибок, что должно быть точно так же, как и при использовании встроенного условного синтаксиса, как описано выше!?!

if(ilo.Description.Equals(string.Empty))
{
    database.AddInParameter(cmd, "@description", DbType.String, DBNull.Value);
}
else
{
    database.AddInParameter(cmd, "@description", DbType.String, ilo.Description);
}

Я искал другие посты и нашел следующий, но он не отвечает на мой вопрос.

EntLib Way to Bind "Null" Значение в параметр

Меня больше интересует ПОЧЕМУ, потому что очевидный обходной путь состоит в том, чтобы просто использовать оператор if / else вместо встроенного (троичного) синтаксиса?

По этой ссылке есть своего рода ответ, но мне бы хотелось получить лучшее объяснение, потому что мне кажется, что Б.С. это не работает; Я бы назвал это ошибкой!

http://msdn.microsoft.com/en-us/library/ty67wk28.aspx

 Steve01 июн. 2012 г., 17:44
Вы можете получить подробную информацию о троичного оператора и такого рода проблемыin this answer
 Jim01 июн. 2012 г., 18:24
Я также хотел бы прокомментировать, что меня очень впечатлили скорость и точность ответов на эту ветку. Это сообщество потрясающе! Спасибо всем!
 Jim01 июн. 2012 г., 18:17
Спасибо Стив. Ваша ссылка была то, что я искал на самом деле. Я думаю, что это глупый аспект .NET; почему они просто не оценивают, соответствуют ли типы каждого возможного результата утверждению. т.е. если вы говорите Object o = (someBool)? someInt32: someString; Вы получаете сообщение об ошибке, но насколько легко было бы оценить, что оба результата могут быть неявно преобразованы в Object вместо оценки, может ли someString быть приведена к someInt32? Мне это кажется глупым, но я думаю, что так оно и есть. Спасибо!

Ответы на вопрос(4)

Это то, что я нашел в другой ветке, и это отлично сработало для меня:

yourVariable ?? (object)DBNull.Value

Я надеюсь, что это помогает.

Энтони действительно прав, поэтому он должен получить правильный ответ, однако здесь есть метод расширения, потому что мне скучно ...

    public static object NullCheck(this string self)
    {
        return (string.IsNullOrEmpty(self)) ? (object)DBNull.Value : self;
    }

Использование в вашем сценарии:

database.AddInParameter(cmd, "@description", DbType.String, 
                           ilo.Description.NullCheck());
 Jim01 июн. 2012 г., 18:29
Хорошая вещь. Несмотря на то, что я, вероятно, не буду использовать этот метод, он просто научил меня кое-чему о C #, чего я раньше не знал; как будто я даже раньше не замечал метод IsNullOrEmpty в String. Я просто очень привык к Java и рад узнать больше о C #. Спасибо!
 06 июн. 2012 г., 16:04
Не задумываясь, подумав об этом, может быть лучше поместить метод расширения в сам объект ParameterCollection / database, чтобы обеспечить оболочку, которая обрабатывает нули так, как вы хотите.

Вы получаете ошибку компиляции, потому что обе части троичного выражения должны быть одного типа. Самый простой обходной путь для этой конкретной ситуации - привести оба объекта:

database.AddInParameter(cmd, "@description", DbType.String, 
                           (ilo.Description.Equals(string.Empty)) ?
                            (object) DBNull.Value :
                            (object) ilo.Description);
 01 июн. 2012 г., 17:42
Как предположил Лениберезовский, здесь также лучше использовать null, а не DBNull.Value. Я думаю, что вам нужно использовать только DBNull.Value при чтении из чтения данных или набора данных.
Решение Вопроса

Это распространенная ошибка, которую люди получают при использовании условного оператора. Чтобы исправить это, просто приведите один или оба результата к общему базовому типу.

ilo.Description.Equals(string.Empty) 
     ? (object)DBNull.Value 
     : ilo.Description

Проблема обнаружена в сообщении об ошибке, которое вы видели.

Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'string'

Строка не является DBNull, а DBNull не является строкой. Следовательно, компилятор не может определить тип выражения. Используя приведение к общему базовому типу (в этом случаеobject), вы создаете сценарий, в котором компилятор может затем определить, что строка также может быть преобразована в объект, поэтому тип выражения можно определить как объект, что также хорошо согласуется с тем, что ваша строка кода также ожидает в качестве аргумента DbParameter.

 Jim01 июн. 2012 г., 18:19
Комментарий Стива дает ссылку с более подробной информацией, но ваш ответ также очень правильный. Мне просто кажется глупым делать это. Я верю, что в Java этого не происходит.

Ваш ответ на вопрос