繁体   English   中英

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

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

当我尝试从datagridview中删除引用表Famille的行时,出现此错误是:

System.Data.dll中发生了类型为'System.Data.SqlClient.SqlException'的未处理异常。其他信息:DELETE语句与REFERENCE约束“ FK_NatureCharge_Famille”相冲突。 数据库“ Tresorerie”的表“ dbo.NatureCharge”的“ IdFam”列中发生了冲突。 该语句已终止。

此表(Famille和NatureCahrge) 在此处输入图片说明
顺便说一句,Famille部分可以删除datagridview中的多行。 我尝试添加删除NaturCharge 1st(以注释删除“ Nature”开头)
编码 :

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

附加信息:DELETE语句与REFERENCE约束“ FK_NatureCharge_Famille”冲突。 数据库“ Tresorerie”的表“ dbo.NatureCharge”的“ IdFam”列中发生了冲突。

看起来DELETE语句似乎不正确

更新代码

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

和同样的错误...

您可以使用级联删除原始表中的所有外键记录。

在某些DBMS中,它是在外键约束级别上设置的,而在删除本身上则是设置的。

检查以下链接以获取更多信息。

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

在这种情况下,我建议您在外键操作中使用级联删除,与您自己删除相关的寄存器相比,您可以使代码库更加简化。

但是,如果您仍然想自己做,可以使用我修改过的这段代码

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

我的解决方案:在删除表之前,我必须删除所有与之相关的表。 因此,我的操作很简单,与删除NatureCharge表中具有相同ID的行相比,我得到了所选DataGridView的IdFam

我的代码:

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