2016-07-18 2 views
0

Я создаю инструмент C#, который подключается к базе данных SQL для управления пользователями для другой программы, которую я создал. Я показываю Пользователей в ListBox, и я могу добавлять/удалять пользователей. После того, как я удалил некоторые профили, все стало странно, и я подумал, что это может иметь какое-то отношение к тому, как я удаляю строку из базы данных. Я использую Id, который автоматически увеличивается с каждым новым созданием пользователя. Это мой код для удаления из базы данных:Удалить строку SQL и изменить ID

using (conn = new SqlConnection(connectionString)) 
using (SqlCommand command = new SqlCommand("DELETE FROM myDatabase WHERE Id = '" + (listBox1.SelectedIndex + 1) + "'", conn)) 
{ 
    conn.Open(); 
    command.ExecuteNonQuery(); 
} 

и это, как я загружаю пользователь в мой ListBox:

using (conn = new SqlConnection(connectionString)) 
using (SqlDataAdapter sqlAdapt = new SqlDataAdapter("SELECT * FROM myDatabase", conn)) 
{ 
    DataTable dataTable = new DataTable(); 
    sqlAdapt.Fill(dataTable); 
    listBox1.DisplayMember = "Name"; 
    listBox1.ValueMember = "Id"; 
    listBox1.DataSource = dataTable; 
} 

Как я могу удалить правильную строку из базы данных?

+2

Вы должны использовать SelectedValue вместо SelectedIndex. Тем не менее, для меня все еще неясно, какова ваша проблема. Что такое «странное» для списка? – Kinetic

+0

сколько идентификаторов находится в списке ..? и как вы можете ожидать, что он удалит все ID, если в базе данных имеется более одного уникального идентификатора?? вы подумали об обертывании кода вокруг цикла foreach, а также переформатировании инструкции Delete для использования правильных параметризованных значений для запроса ..? и сохраните SelectedValue в переменной, не говоря уже о том, что вам не нужно '('обернуто вокруг вашего объекта listBox'. Узнайте, как построить параметризованный запрос .. или создайте хранимую процедуру и правильно передайте значения. – MethodMan

+0

Пожалуйста, подумайте об использовании LINQ2SQL или EF Нет, это не решение вашей проблемы - вот почему это комментарий. – SQLMason

ответ

3

Вы должны использовать свойство SelectedValue найти свой идентификатор не SelectedIndex

if(listBox1.SelectedValue != null) 
{ 
    int userID = Convert.ToInt32(listBox1.SelectedValue); 
    using (conn = new SqlConnection(connectionString)) 
    using (SqlCommand command = new SqlCommand("DELETE FROM myDatabase WHERE Id = @uid", conn)) 
    { 

     conn.Open(); 
     command.Parameters.Add("@uid", MySqlDbType.Int32).Value = userID; 
     command.ExecuteNonQuery(); 
    } 
} 

Проблема SelectedIndex в том, что это значение от 0 до максимального числа элементов в ListBox. Это значение не имеет никакого отношения к идентификатору пользователя, который автоматически рассчитывается вашей базой данных. (После всего одного удаления и одного добавить эти значения не синхронизированы)

Обратите также внимание, что текст sql никогда не должен строиться с использованием конкатенации строк. Это хорошо известная проблема безопасности, которая называется Sql Injection.

+0

Стив говорит: «Обратите внимание, что текст sql никогда не должен строиться с использованием конкатенации строк» ​​применяются только в том случае, если внешние пользователи имеют доступ к вашему входу Если вы используете значения из предопределенного списка, это не будет проблемой – JSON

+1

И так? Использование параметров лучше по многим причинам. Не только для Sql Injection. MySql), но с Sql Server хорошо известно, что параметризованный запрос может быть оптимизирован с помощью механизма базы данных. Не используйте эту привычку, даже если она «безопасна». – Steve

+0

@JSO N Обратите внимание, что OP * также * указывает на то, что selectedindex конвертирует число в текст случайно - для того, чтобы это произошло с параметрами, это более очевидно. – Plutonix

-1
"DELETE FROM myDatabase WHERE Id = '" + (listBox1.SelectedIndex + 1) + "'" 

Я не уверен в mySQL, но похоже, что вы передаете строку вместо int. Когда вы передаете параметр в виде числа, вы должны удалить «». так, это будет выглядеть так:

"DELETE FROM myDatabase WHERE Id = " + (listBox1.SelectedValue) 
+3

'+ (listBox1.SelectedValue)' Неправильно ..вам не нужен знак '+', также не поощряйте других использовать конкатенированный запрос, это вводит Sql Injection .. всегда рекомендую использовать параметризованные запросы – MethodMan

+0

Вы правы. Однако, я хотел сказать, что он передал параметр как строку вместо int. Концепция его вопроса нуждалась в разъяснении, а не в правильном способе этого. – Tomerz

+0

Дело в том, что вам не нужно обертывать listbox1 вокруг '()' независимо от того, .. его вопрос в отношении разъяснения был прямым, вы никогда не должны строить запрос таким образом. возможно, вам следует прочитать «Sql Injection» еще раз, что ваш ответ неверен, и вы публикуете неверную информацию, которую кто-то потенциально может использовать в качестве неправильного примера о том, как что-то сделать – MethodMan