Ошибка приведения объекта

#c#

#c#

Вопрос:

В моем методе addProduct что-то не так с моим кодом. Я получаю сообщение о том, что объект не может быть преобразован из DBNull в другие типы, когда я тестирую свой код. У кого-нибудь есть идеи, откуда эта проблема?

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
 namespace ProductMaintenance
{
class ProductDB
{

    public static Product GetProduct(string code)
    {
        SqlConnection connection = MMABooksDB.GetConnection();
        string select = "SELECT ProductCode, Description, UnitPrice "
             "FROM Products "
             "WHERE ProductCode = @ProductCode";
        SqlCommand selectCommand = new SqlCommand(select, connection);
        selectCommand.Parameters.AddWithValue("@ProductCode", code);
        try
        {
            connection.Open();

            SqlDataReader prodReader = selectCommand.ExecuteReader(CommandBehavior.SingleRow);
            if (prodReader.Read())
            {
                Product product = new Product();
                product.Code = prodReader["ProductCode"].ToString(); ;
                product.Description = prodReader["Description"].ToString();
                product.Price = ((decimal)prodReader["Price"]);
                return product;
            }
            else
            {
                return null;
            }


        }
        catch (SqlException ex)
        {
            throw ex;
        }
        finally
        {
            connection.Close();
        }
    }
    public static bool UpdateProduct(Product oldProduct, Product newProduct)
    {
        SqlConnection connection = MMABooksDB.GetConnection();
        string updateStatement = "UPDATE Products SET "   "Description = @NewDescription, "   "UnitPrice = @NewUnitPrice, "   "WHERE ProductCode = @oldProductCode "   "AND Description = @OldDescription "   "AND UnitPrice = @OldUnitPrice";
        SqlCommand updateCommand =
            new SqlCommand(updateStatement, connection);
        updateCommand.Parameters.AddWithValue(
            "@NewDescription", newProduct.Description);
        updateCommand.Parameters.AddWithValue(
            "@NewUnitPrice", newProduct.Price);
        updateCommand.Parameters.AddWithValue(
            "@OldProductCode", oldProduct.Code);
        updateCommand.Parameters.AddWithValue(
            "@OldDescription", oldProduct.Description);
        updateCommand.Parameters.AddWithValue(
            "@OldUnitPrice", oldProduct.Price);

        try
        {
            connection.Open();
            int count = updateCommand.ExecuteNonQuery();
            if(count > 0)

                return true;
            else
                return false;
        }
        catch(SqlException ex)
        {
            throw ex;
        }
        finally
        {
            connection.Close();
        }
    }
    public static int AddProduct(Product product)
    {
        SqlConnection connection = MMABooksDB.GetConnection();
        string insertStatement = "INSERT Products "   "(ProductCode, Description, UnitPrice) "   "VALUES (@ProductCode, @Description, @UnitPrice)";
        SqlCommand insertCommand = new SqlCommand(insertStatement, connection);
        insertCommand.Parameters.AddWithValue("@ProductCode", product.Code);
        insertCommand.Parameters.AddWithValue("@Description", product.Description);
        insertCommand.Parameters.AddWithValue("@UnitPrice", product.Price);
        try
        {
            connection.Open();
            insertCommand.ExecuteNonQuery();
            string selectStatement = "SELECT IDENT_CURRENT('Products') FROM Products";
            SqlCommand selectCommand = new SqlCommand(selectStatement, connection);
            int productC = Convert.ToInt32(selectCommand.ExecuteScalar());

            return productC;
        }
        catch (SqlException ex)
        {
            throw ex;
        }
        finally
        {
            connection.Close();
        }
    }
}
  

}

Комментарии:

1. перед приведением необходимо проверить наличие null. всегда.

2. Вы получили сообщение? В какой строке, где? Какие значения вы используете?

3. Сообщение об ошибке означает то, что оно говорит. Если нет данных для одного из столбцов, считыватель вернет DBNull. Вы не можете привести или преобразовать его, чтобы использовать для него toString .

4. Мой взгляд был обращен на то же самое. Но в вопросе говорится, что возникает исключение, AddProduct которое не содержит a SqlDataReader .

Ответ №1:

Вы выбираете IDENT_CURRENT , который может возвращать значение null.

Смотрите эту документацию.

Возвращает значение NULL при ошибке или если вызывающий объект не имеет разрешения на просмотр объекта.

В SQL Server пользователь может просматривать только метаданные защищенных объектов, которыми владеет пользователь или на которые у пользователя есть разрешение. Это означает, что встроенные функции, передающие метаданные, такие как IDENT_CURRENT, могут возвращать значение NULL, если у пользователя нет никаких разрешений на объект.

Судя по описываемой вами ошибке, похоже, что это ошибка. Ваш AddProduct метод не будет пытаться привести значение null, когда он выполняет INSERT , поэтому, скорее всего, это значение null при попытке получить идентификатор в

 int productC = Convert.ToInt32(selectCommand.ExecuteScalar());
  

Поскольку вызов to IDENT_CURRENT является единственным оператором в этой команде SQL, это практически исключает синтаксическую или другую ошибку в SQL, что сузило бы это до разрешений.

Там есть немного догадок и выводов, но я подозреваю, что это именно то, в чем дело.

(Если ошибка вызвана AddProduct методом, нет необходимости публиковать все остальное. Многие люди, включая меня, придут к выводу, что ошибка возникает при доступе к SqlDataReader , поскольку вы не проверяете там нули. Но, как вы сказали, это не метод, вызывающий исключение. Это просто легко пропустить, когда так много нерелевантного кода.)