繁体   English   中英

如何从 Visual Studio 的表中删除特定记录?

[英]How do I delete specific records from a table in visual studio?

我已经多次编写和重写代码,以便在文本框中输入“名称”并单击一个按钮时删除记录,该按钮将删除与输入的名称相关的行。 但是,当我运行程序并单击按钮时,会弹出消息框,指出特定记录已被删除,但是当表显示在数据网格视图中时,记录仍然存在(它们尚未被删除)从表中删除)请检查我的编码并告诉我它有什么问题,我该如何解决? 谢谢:) 另外我不得不说,我只学习了 C# 编程的基本知识。这是我的编码:

private void btnremove_Click(object sender, EventArgs e)
{
    con.Open();
    DialogResult ans = MessageBox.Show("Are you sure you want to remove the selected records?", 
        "Confirmation For Membership Cancellation", MessageBoxButtons.YesNo, 
        MessageBoxIcon.Question);
    if (ans==DialogResult.Yes)
    {
        string sqldelete = "DELETE FROM membersdetails WHERE Name='" + txtname.Text + "'";
        string deletesql = "DELETE FROM currentstatus WHERE Name_='" + txtname.Text + "'";
        com = new SqlCommand(sqldelete,con);
        com = new SqlCommand(deletesql, con);
        SqlDataAdapter sqldataadapter = new SqlDataAdapter(com);
        com.ExecuteNonQuery();
        MessageBox.Show("Records have been removed- Membership has been  cancelled", 
           "Membership Cancellation", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    con.Close();
    com.Dispose();
}

在当前状态下,您的代码存在一些问题:

  1. 下面的块,您正在覆盖删除机制的一部分:

     com = new SqlCommand(sqldelete,con); com = new SqlCommand(deletesql, con); SqlDataAdapter sqldataadapter = new SqlDataAdapter(com); com.ExecuteNonQuery();

    您应该能够将sqldeletedeletesql字符串变量合并为 1 个命令,然后可以将其传递给数据库引擎。

  2. 从编码的角度看,类应遵守单一职责原则,也就是班担心只做一样东西。 在您当前的代码中,UI 需要考虑保持 UI 更新保持 DB 更新。 为了解决这个问题,我们通常会创建存储库,其任务是包装数据库操作。 这还允许您测试应用程序的各个层,并在您决定进行任何更改时为您提供更大的灵活性。

  3. 照原样,您的代码对 SQL 注入攻击是开放的,请考虑使用准备好的语句来解决这个问题。

  4. 除此之外,我看不出您的删除代码有任何本质上的错误。 但是,可能是您的网格没有被刷新(而您认为是)。 检查这一点的最快和最好的方法是使用 SQL Management Studio(或 Azure Data)之类的东西连接到您的数据库并直接查询表。

ExecuteNonQuery()必须在最后一个新实例之后和之前执行:

    com = new SqlCommand(sqldelete,con);
    com.ExecuteNonQuery();
    com = new SqlCommand(deletesql, con);
    com.ExecuteNonQuery();
    
    // Then, you can show the table
    string sqlSelect = "SELECT * FROM yourtable WHERE bla bla...";
    SqlDataAdapter sqldataadapter = new SqlDataAdapter(sqlSelect, con);
    DataTable tbl = new DataTable();
    sqldataadapter.Fill(tbl);
    yourDataGridView.DataSource = tbl;

试试这个,我希望它可以帮助。

以下是一个示例,可能需要进行一些更改以适应您的代码。 这个想法是使用 BindingSource 设置 DataGridView 数据源,该数据源具有表中的成员详细信息所需的列。 数据操作在一个类中,将前端操作与数据操作分开。 请注意,不需要过大的 SqlDataAdapter。

对于删除操作,最好使用主键,因为它是常量,而名称可能会在某些时候改变。

以下类是读取和删除操作的模型,请确保您了解它不是复制粘贴解决方案,因此在尝试之前花点时间阅读代码。

数据类

using System.Collections.Generic;
using System.Data.SqlClient;

namespace YourNamespace
{
    public class MembershipOperations
    {
        /// <summary>
        /// Connection string to your database
        /// - change TODO to your environment
        /// - Integrated Security (check this too)
        /// </summary>
        private static readonly string _connectionString =
            "Data Source=****TODO****;" +
            "Initial Catalog=****TODO****;" +
            "Integrated Security=True";

        /// <summary>
        /// Delete a single member by primary key
        /// Recommend adding a try-catch to the open and ExecuteNonQuery lines
        /// </summary>
        /// <param name="memberIdentifier">Member primary key</param>
        /// <returns>
        /// Success of the operation
        /// </returns>
        public static bool RemoveSingleOrder(int memberIdentifier)
        {
            bool success = false;

            string deleteStatement = "DELETE FROM membersdetails  WHERE id = @id";

            using (var cn = new SqlConnection { ConnectionString = _connectionString })
            {
                using (var cmd = new SqlCommand { Connection = cn, CommandText = deleteStatement })
                {

                    cmd.Parameters.AddWithValue("id", memberIdentifier);
                    cn.Open();
                    success = cmd.ExecuteNonQuery() == 1;
                }
            }

            return success;

        }
        /// <summary>
        /// Provides a list which in the frontend a user can select
        /// a member such as a ComboBox or ListBox etc.
        ///
        /// When they select a user you have code to cast the selected item
        /// to a MemberDetails instance and pass the primary key to the RemoveSingleOrder
        /// method.
        ///
        /// Note in the frontend if there are many members consider providing a incremental
        /// search feature to the frontend control displaying member details.
        /// </summary>
        /// <returns></returns>
        public static List<MemberDetails> GetMemberDetails()
        {
            var memberDetails = new List<MemberDetails>();

            /*
             * - Create a connection and command object with
             *   SELECT column names including 'id' primary key
             *
             * - Use a DataReader to loop through records into
             *   memberDetails variable
             */

            return memberDetails;
        }
    }
    /// <summary>
    /// Place in a class file named  MemberDetails.cs
    /// </summary>
    public class MemberDetails
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        // more properties

        /// <summary>
        /// Optional, can assist with debugging and/or
        /// for display purposes
        /// </summary>
        /// <returns></returns>
        public override string ToString() => $"{FirstName} {LastName}";

    }
}

使用默认按钮提问的辅助方法是“否”,而不是“是”。

使用 System.Windows.Forms;

namespace YourNamespace
{
    public static class Dialogs
    {
        public static bool Question(string text)
        {
            return (MessageBox.Show(
                text,
                Application.ProductName,
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button2) == DialogResult.Yes);
        }
    }
}

表格代码

using System;
using System.Windows.Forms;

namespace YourNamespace
{
    public partial class Form1 : Form
    {
        private readonly BindingSource _membersBindingSource = new BindingSource();
        public Form1()
        {
            InitializeComponent();
            Shown += Form1_Shown;
        }
        /// <summary>
        /// Setup columns in the IDE for MembersDataGridView that
        /// exclude the primary key
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Shown(object sender, EventArgs e)
        {
            MembersDataGridView.AutoGenerateColumns = false;
            _membersBindingSource.DataSource = MembershipOperations.GetMemberDetails();
            MembersDataGridView.DataSource = _membersBindingSource;
        }

        private void RemoveMemberButton_Click(object sender, EventArgs e)
        {
            if (_membersBindingSource.Current == null) return;

            var member = (MemberDetails)_membersBindingSource.Current;

            if (!Dialogs.Question($"Remove {member}")) return;

            if (!MembershipOperations.RemoveSingleOrder(member.Id))
            {
                MessageBox.Show($"Failed to remove {member}");
            }
        }
    }
}

暂无
暂无

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

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