TheBigBearNow Ответов: 2

C# недопустимая ошибка приведения и, возможно, проблемы с таблицей.


Всем привет,
Я создаю нового клиента, и в моем запросе C# SQL я получаю ошибку “недопустимая ошибка операции приведения.” У меня есть пользователь, и я получаю информацию от этого пользователя и вставляю ее в клиента. Я получал ошибку внешнего ключа но я удалил внешний ключ чтобы вставить данные теперь я получаю недопустимые операции приведения,

        private void BtnProfileEdit_Click(object sender, RoutedEventArgs e)
        {            
            EnableControls();

            if (boolBtnPush == true)
            {
                if (BtnProfileEdit.Content.Equals("Save"))
                {
                    if (currentCustomer.IsCustomer == true)
                    {
                        if (TextboxFirstName.Text.Equals(""))
                        {   //Display messagebox so user MUST enter firstname.
                            MessageBox.Show("You 'MUST' enter a First name,", "WARNING", MessageBoxButton.OK);
                        }
                        else
                        {
                            try
                            {
                                customerLoaded = new Customer(TextboxFirstName.Text,
                                    TextboxLastName.Text, TextboxAddress.Text, TextboxCity.Text,
                                    ComboboxState.SelectedValue.ToString(), TextboxZip.Text, TextEmailAddress.Text);
                                UsersDB.UpdateCustomer(customerLoaded);

                                Window SrcCustomerScreen = new CustomerScreen(currentCustomer);
                                SrcCustomerScreen.Show();
                                Close();
                            }
                            catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
                        }
                    }
                    else
                    {
                        MessageBox.Show("You must press 'Yes' selecting combobox customer", "Unacceptable", MessageBoxButton.OK);
                    }                  
                }
            }
            //ON THE FIRST BUTTON CLICK DO THIS SO ON SECOND ABOVE CODE IS EXECUTED.
            boolBtnPush = true;
            BtnProfileEdit.Content = "Save";
        }

        private void Btntest_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(currentCustomer.ToString());
        }

        private void CboCustomer_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string cboValue = "";
            if (CboCustomer.SelectedIndex > 0)
                cboValue = ((ComboBoxItem)CboCustomer.SelectedItem).Content.ToString();
            if(cboValue.Equals("Yes"))
            {
                boolIsCustomer = true;
                User addCustomer = null;
                Customer newCustomer = null;

                MessageBoxResult result = MessageBox.Show("Updating database to customer status.",
                    "Customer Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                if (result == MessageBoxResult.Yes)
                {
                    try
                    {
                        addCustomer = new User(currentCustomer.UserID, currentCustomer.Username,
                            currentCustomer.Password, currentCustomer.IsAdmin, currentCustomer.UserCreatedDate, boolIsCustomer);
                        UsersDB.UpdateCurrentUser(addCustomer);
                        //Create New Customer
                        newCustomer = new Customer(currentCustomer.UserID, currentCustomer.Username, null, null,
                                                    null, null, null, null);
                        UsersDB.CreateCustomer(newCustomer);

                        //Load the newly created customer object so it can be read.
                        customerLoaded = UsersDB.ReadCustomerById(currentCustomer.UserID);
                        PopulateControls(customerLoaded);
                    }
                    catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
                }
            }
        }
public static int CreateCustomer(Customer customer)
        {
            string SQLcreateQuery = "INSERT INTO Customers (CustomerId, FirstName, LastName, Address, " +
                "City, State, ZipCode, EmailAddress) VALUES(@id, @fn, @ln, @ad, @ci, @st, @zc, @ea)";
            SqlCommand cmdCreate = new SqlCommand(SQLcreateQuery, connection);
            cmdCreate.Parameters.AddWithValue("@id", customer.UserID);
            cmdCreate.Parameters.AddWithValue("@fn", customer.FirstName);
            cmdCreate.Parameters.AddWithValue("@ln", customer.LastName ?? Convert.DBNull);
            cmdCreate.Parameters.AddWithValue("@ad", customer.Address ?? Convert.DBNull);
            cmdCreate.Parameters.AddWithValue("@ci", customer.City ?? Convert.DBNull);
            cmdCreate.Parameters.AddWithValue("@st", customer.State ?? Convert.DBNull);
            cmdCreate.Parameters.AddWithValue("@zc", customer.ZipCode ?? Convert.DBNull);
            cmdCreate.Parameters.AddWithValue("@ea", customer.EmailAddress ?? Convert.DBNull);
            try
            {
                connection.Open();
                cmdCreate.ExecuteNonQuery();
                string SQLselect = "SELECT @@IDENTITY FROM Customers";
                SqlCommand cmdSELECT = new SqlCommand(SQLselect, connection);
                int CustomerId = (int)cmdSELECT.ExecuteScalar();
                return CustomerId;
            }
            catch (Exception ex) { throw ex; }
            finally { connection.Close(); }
        }


Что я уже пробовал:

удаление внешнего ключа
и многое другое тоже

CHill60

Вы получаете ошибку при выполнении запроса или раньше? Какова ваша схема таблицы и соответствует ли она тому, что вы пытаетесь вставить?
Кстати, слепое удаление внешних ключей не является хорошим способом отладки вашего кода - Вы просто хватаетесь за соломинку

Richard Deeming

SELECT @@IDENTITY FROM Customers

Это не так. @@ИДЕНТИЧНОСТЬ[^] завод.

ZurdoDev

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

akshay_zz

Надеюсь, вы отладили свой код.Так что можете ли вы сказать нам, на какой линии вы получаете ошибку?

-cmdCreate.Метод executenonquery();
-int CustomerId = (int)cmdSELECT.Executescalar так();

или любой другой. Было бы здорово, если бы вы могли видеть, какие значения вы передаете, что делает эти значения совпадающими с типом данных столбца таблиц.

2 Ответов

Рейтинг:
1

Ravi Gaur 11

connection.Open();
      cmdCreate.ExecuteNonQuery();
      string SQLselect = "SELECT @@IDENTITY FROM Customers";
      SqlCommand cmdSELECT = new SqlCommand(SQLselect, connection);
      int CustomerId = (int)cmdSELECT.ExecuteScalar();
      return CustomerId;


ошибка находится в этом разделе,
проверьте, что выходит, а затем преобразуйте/бросьте его
cmdSELECT.ExecuteScalar()


CHill60

Более вероятно, что команда ExecuteScalar возвращает null. Так что сначала проверьте на нуль.

Ravi Gaur 11

также думайте так, потому что "SELECT @@IDENTITY FROM Customers" вернет null

Рейтинг:
0

CHill60

Ваша команда ExecuteScalar возвращает Null (см. комментарий от @Richard-Deeming)

Вы должны проверить наличие null, прежде чем пытаться привести возвращаемое значение.

Аккуратный способ сделать это заключается в следующем:

object result = cmdSELECT.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int CustomerId = Convert.ToInt32(result);
Что работает потому что Convert.ToInt32(null) возвращает 0

Решение адаптировано из ответа Нихила Вартака здесь[^]

Теперь рассмотрим фундаментальную проблему в вашем коде.
string SQLselect = "SELECT @@IDENTITY FROM Customers";
                SqlCommand cmdSELECT = new SqlCommand(SQLselect, connection);
он не вернет вам идентификатор строки, которую вы только что вставили. Даже если бы это было так, что если бы другой пользователь вставил строку в долю секунды между вашими двумя sql-операторами?

Измените свою SQL-вставку, чтобы вернуть сгенерированный идентификатор, например (при условии, что ваш столбец identity вызывается ID)
string SQLcreateQuery = "INSERT INTO Customers (CustomerId, FirstName, LastName, Address, City, State, ZipCode, EmailAddress) OUTPUT INSERTED.ID VALUES(@id, @fn, @ln, @ad, @ci, @st, @zc, @ea)";
Затем вам нужно будет использовать ExecuteScalar для запуска SQL не требуется ExecuteNonQuery
object result = cmdSQLcreateQuery.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int CustomerId = Convert.ToInt32(result);