2015-11-04 2 views
0

Когда я попытался удалить строку из DataGridView см стола Famille, я получаю эту ошибку:Как удалить запись с ограничением внешнего ключа в другую таблицу?

Необработанного исключение типа «System.Data.SqlClient.SqlException» произошло в System.Data.dll Дополнительного информация: заявление DELETE противоречит ограничению REFERENCE «FK_NatureCharge_Famille». Конфликт произошел в базе данных «Tresorerie», таблица «dbo.NatureCharge», столбец «IdFam». Заявление было прекращено.

это таблицы (Famille и NatureCahrge) enter image description here
К слову, Famille часть может удалить несколько строк в DataGridView. Я пытался добавить удалить 1-й NaturCharge (он начинается с комментария удалить Природу)
Код:

private void DeleteFamBtn_Click(object sender, EventArgs e) 
    { 
     List<DataGridViewRow> selectedRows = (from row in DataGridViewFamille.Rows.Cast<DataGridViewRow>() 
               where Convert.ToBoolean(row.Cells["checkBoxColumn"].Value) == true 
               select row).ToList(); 


     if (MessageBox.Show(string.Format("Do you want to delete {0} rows?", selectedRows.Count), "Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes) 
     { 
      //delete Nature de Charge before delete Famille 
      foreach (DataGridViewRow row in selectedRows) 
      { 
       try 
       { 
        using (SqlConnection con = new SqlConnection(connstring)) 
        { 
         con.Open(); 
         using (SqlCommand command = new SqlCommand("DELETE NatureCharge FROM NatureCharge n INNER JOIN Famille f on n.IdFam = f.IdFam WHERE IdNat = @IdNat", con)) 
         { 
          command.Parameters.AddWithValue("@IdFam", row.Cells["IdFam"].Value); 
          command.ExecuteNonQuery(); 
         } 
         con.Close(); 
        } 
       } 
       catch (SystemException ex) 
       { 
        MessageBox.Show(string.Format("An error occurred: {0}", ex.Message)); 
       } 

      } 

      //Delete Famille 
      foreach (DataGridViewRow row in selectedRows) 
      { 
       using (SqlConnection con = new SqlConnection(connstring)) 
       { 
        using (SqlCommand cmd = new SqlCommand("DELETE FROM Famille WHERE IdFam = @IdFam", con)) 
        { 
         cmd.CommandType = CommandType.Text; 
         cmd.Parameters.AddWithValue("@IdFam", row.Cells["IdFam"].Value); 
         con.Open(); 
         cmd.ExecuteNonQuery(); 
         con.Close(); 
        } 
       } 
      } 

      //Update the datagridview 
      this.BindGrid(); 
     } 
    } 

ошибка показывает, с линией (это для Famille части) `cmd.ExecuteNonQuery();` `

Дополнительная информация: ВЕЬЕТЕ противоречие с ссылочное ограничение "FK_NatureCharge_Famille". Произошел конфликт в базе данных "Tresorerie", таблица "dbo.NatureCharge", столбец IdFam.

Это выглядит УДАЛИТЬ утверждение не кажется правильным

код Обновление

//delete Nature de Charge before delete Famille 
      foreach (DataGridViewRow row in selectedRows) 
      { 
       try 
       { 
        using (SqlConnection con = new SqlConnection(connstring)) 
        { 
         con.Open(); 
         using (SqlCommand command = new SqlCommand("DELETE NatureCharge FROM NatureCharge n INNER JOIN Famille f on n.IdFam = f.IdFam WHERE IdNat = @IdNat", con)) 
         { 
          command.ExecuteNonQuery(); 
         } 
         con.Close(); 
        } 
       } 
       catch (SystemException ex) 
       { 
        MessageBox.Show(string.Format("An error occurred: {0}", ex.Message)); 
       } 
      } 

и та же ошибка ...

+1

Вы используете неправильный параметр в первом запросе удаления. Текст запроса запрашивает @ IdNat, но вы добавляете @ IdFam в коллекцию параметров .... command.Parameters.AddWithValue ("@ IdFam", row.Cells ["IdFam"]. Значение); – dbugger

+0

ОК Я изменяю код для удаления записей в таблице NatureCharge, см. Обновление – Amin

ответ

1

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

Но если вы все еще хотите сделать это самостоятельно, вы можете использовать этот кусок кода, который я motified

private void DeleteFamBtn_Click(object sender, EventArgs e) 
{ 
    List<DataGridViewRow> selectedRows = (from row in DataGridViewFamille.Rows.Cast<DataGridViewRow>() 
              where Convert.ToBoolean(row.Cells["checkBoxColumn"].Value) 
              select row).ToList(); 


    if (MessageBox.Show(string.Format("Do you want to delete {0} rows?", selectedRows.Count), "Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes) 
    { 
     //delete Nature de Charge before delete Famille 
     var idsToDelete = selectedRows.Select(row => row.Cells["IdFam"].Value).ToList(); 
     try 
     { 
      using (var con = new SqlConnection(connstring)) 
      { 
       var ids = string.Join(",", idsToDelete); 
       using (var deleteNatures = new SqlCommand("DELETE FROM NatureCharge IdFam IN " + ids, con)) 
       using (var deleteFamilles = new SqlCommand("DELETE FROM Famille WHERE Id IN " + ids, con)) 
       { 
        deleteNatures.Parameters.AddWithValue("@IdFam", row.Cells["IdFam"].Value); 
        con.Open(); 
        deleteNatures.ExecuteNonQuery(); 
        deleteFamilles.ExecuteNonQuery(); 
       } 

       con.Close(); 
      } 
     } 
     catch (SystemException ex) 
     { 
      MessageBox.Show(string.Format("An error occurred: {0}", ex.Message)); 
     } 

     //Update the datagridview 
     this.BindGrid(); 
    } 
} 
1

Вы можете удалить все иностранные ключевые записи в их исходных таблицах с использованием каскада.

В некоторых СУБД его набор устанавливается на уровне ограничения внешнего ключа, а некоторые - на самом удалении.

Проверьте, пожалуйста, следующую информацию.

http://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php

0

Мое решение: Перед удалили таблицу, я должен удалить все связанные таблицы, которые относятся с. Так мой OCDE прост, я получаю IdFam выбранного DataGridView, чем я удалить строку с тем же ID в таблице NatureCharge в

Мой код:

private void DeleteFamBtn_Click(object sender, EventArgs e) 
    { 
     List<DataGridViewRow> selectedRows = (from row in DataGridViewFamille.Rows.Cast<DataGridViewRow>() 
               where Convert.ToBoolean(row.Cells["checkBoxColumn"].Value) == true 
               select row).ToList(); 

     if (MessageBox.Show(string.Format("Do you want to delete {0} rows?", selectedRows.Count), "Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes) 
     { 
      //delete Nature de Charge before delete Famille 
      foreach (DataGridViewRow row in selectedRows) 
      { 
       int aa = Convert.ToInt32(row.Cells["IdFam"].Value); 
       conn = new SqlConnection(connstring); 
       conn.Open(); 
       comm = new SqlCommand("DELETE FROM NAtureCharge WHERE IdFam ='" + aa + "'", conn); 
       try 
       { 
        comm.ExecuteNonQuery(); 
        //MessageBox.Show("Deleted..."); 
       } 
       catch (Exception) 
       { 
        MessageBox.Show("Not Deleted"); 
       } 
       finally 
       { 
        conn.Close(); 
       } 
      } 

      //Delete Famille 
      foreach (DataGridViewRow row in selectedRows) 
      { 
       using (SqlConnection con = new SqlConnection(connstring)) 
       { 
        using (SqlCommand cmd = new SqlCommand("DELETE FROM Famille WHERE IdFam = @IdFam", con)) 
        { 
         cmd.CommandType = CommandType.Text; 
         cmd.Parameters.AddWithValue("@IdFam", row.Cells["IdFam"].Value); 
         con.Open(); 
         cmd.ExecuteNonQuery(); 
         con.Close(); 
        } 
       } 
      } 

      //Update the datagridview 
      this.BindGrid(); 
     } 
    } 
Смежные вопросы