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

У меня есть следующий бит кода для установки параметра, который будет использоваться в инструкции INSERT для установки столбца VARCHAR в базе данных SQL Server. Мой объект ценности (с именем ilo) имеет свойство, называемое Описание, которое инициализируется в 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" и "string"

Почему?

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

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

Ответы

Ответ 1

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

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

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

Тип условного выражения не может быть определен, потому что нет никакого неявного преобразования между "System.DBNull" и "string"

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

Ответ 2

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

yourVariable ?? (object)DBNull.Value

Надеюсь, это поможет.

Ответ 3

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

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

в вашем сценарии:

database.AddInParameter(cmd, "@description", DbType.String, 
                           ilo.Description.NullCheck());

Ответ 4

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

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