简体   繁体   English

如何删除具有外键约束到另一个表的记录?

[英]How to delete a record with a foreign key constraint to another table?

When I tried to delete row from datagridview refer to table Famille, I get this error is : 当我尝试从datagridview中删除引用表Famille的行时,出现此错误是:

An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll Additional information: The DELETE statement conflicted with the REFERENCE constraint "FK_NatureCharge_Famille". System.Data.dll中发生了类型为'System.Data.SqlClient.SqlException'的未处理异常。其他信息:DELETE语句与REFERENCE约束“ FK_NatureCharge_Famille”相冲突。 The conflict occurred in database "Tresorerie", table "dbo.NatureCharge", column 'IdFam'. 数据库“ Tresorerie”的表“ dbo.NatureCharge”的“ IdFam”列中发生了冲突。 The statement has been terminated. 该语句已终止。

this the tables (Famille and NatureCahrge) 此表(Famille和NatureCahrge) 在此处输入图片说明
By the way, the Famille part can delete multiple row in datagridview. 顺便说一句,Famille部分可以删除datagridview中的多行。 I tried to add delete the NaturCharge 1st (it begins with comment delete Nature) 我尝试添加删除NaturCharge 1st(以注释删除“ Nature”开头)
The code : 编码 :

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();
        }
    }

an error shows with line (it is for Famille part) `cmd.ExecuteNonQuery();`` 一行显示错误(适用于Famille部分)`cmd.ExecuteNonQuery();``

Additional information: The DELETE statement conflicted with the REFERENCE constraint "FK_NatureCharge_Famille". 附加信息:DELETE语句与REFERENCE约束“ FK_NatureCharge_Famille”冲突。 The conflict occurred in database "Tresorerie", table "dbo.NatureCharge", column 'IdFam'. 数据库“ Tresorerie”的表“ dbo.NatureCharge”的“ IdFam”列中发生了冲突。

It looks The DELETE statement doesn't seem to be correct 看起来DELETE语句似乎不正确

Update Code 更新代码

//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));
                }
            }

and the same error... 和同样的错误...

You can delete all the foreign key records in their original tables by using cascade. 您可以使用级联删除原始表中的所有外键记录。

In some DBMSs its set on the level of the foreign key constraint and some on the delete itself. 在某些DBMS中,它是在外键约束级别上设置的,而在删除本身上则是设置的。

Check the following link for more info. 检查以下链接以获取更多信息。

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

I this case I recomend you to use cascade delete in foreign key action, you can matain your code base more simplified than deleting related registers by yourself. 在这种情况下,我建议您在外键操作中使用级联删除,与您自己删除相关的寄存器相比,您可以使代码库更加简化。

But if you still want to do it yourself, you can use this piece of code that I have 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();
    }
}

My solution : Before deleted the table, I must delete all related table that relate with. 我的解决方案:在删除表之前,我必须删除所有与之相关的表。 So My ocde is simple, I get the IdFam of selected DataGridView than I delete the row with same ID in NatureCharge's table 因此,我的操作很简单,与删除NatureCharge表中具有相同ID的行相比,我得到了所选DataGridView的IdFam

My code : 我的代码:

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();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM