打开/关闭sql连接问题

问题描述 投票:0回答:1

我希望你原谅我的头。我在设计用于打开SQL Server数据库的代码时遇到了一些问题。如您所见,frmManageAppointment表单是从其他Winform加载的。到现在为止还挺好。加载后,代码的Connect()部分开始运行并连接到我的SQLDB。到现在为止还挺好。我有第二个脚本,该脚本在按下表单上的“保存”按钮时加载(基本上是保存各种文本框等)。我的猜测是,基于我得到的错误,代码的MakeAppointment部分中conn的第二个实例以某种方式关闭了连接。

我知道我没有正确处理该脚本,因此,我将感谢您的帮助。'''命名空间Scheduler1{公共局部类frmManageAppointment:表格{

    public frmManageAppointment()
    {
        InitializeComponent();
    }


    private void frmManageAppointment_Load(object sender, EventArgs e)
    {
        Connect();

        txtDBConnection.Text = "Connected";
    }

    private void ExitButton_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void SaveButton_Click(object sender, EventArgs e)
    {

        if (string.IsNullOrWhiteSpace(txtSurname.Text))
        {
            MessageBox.Show("Απαιτείται το Επίθετο του Εξεταζόμενου!");
            return;
        }

        if (MakeAppointment())
        {
            MessageBox.Show("Επιτυχής Προσθήκη!");

        }
        else
        {
            MessageBox.Show("Ανεπιτυχής Προσθήκη");

        }


    }

    public void Connect()
    {
        string conString = "Data Source=DIMITRIS-PC\\DIMITRISSQL;Initial Catalog=AppointmentDB;Integrated Security=True";
        SqlConnection conn = new SqlConnection(conString);
        conn.Open();
        if (conn.State == System.Data.ConnectionState.Closed)
        {
            MessageBox.Show("Closed");
        }
        else
        if (conn.State == System.Data.ConnectionState.Open)
        {
            MessageBox.Show("Open");
        }

    }

    public Boolean MakeAppointment()
    {

        string conString = "Data Source=DIMITRIS-PC\\DIMITRISSQL;Initial Catalog=AppointmentDB;Integrated Security=True";
        SqlConnection conn = new SqlConnection(conString);
        string sql = "INSERT INTO Appointmentdbo(Date, Time, Name, Surname, DOB, PatientID, Comments) VALUES ('" + dtpDate.Value.Date.ToString("MM/dd/yyyy") + "','" + comboTime.Text + "','" + txtName.Text + "','" + txtSurname.Text + "','" + dtpDOB.Value.Date.ToString("MM/dd/yyyy") + "','" + txtID.Text + "','" + txtComments.Text + "')";
        SqlCommand cmd = new SqlCommand(sql, conn);
        return cmd.ExecuteNonQuery() > 0;
    }


}

}'''

c# sql-server
1个回答
0
投票

正如评论所指出的,您正在创建一个连接(conn中的Connect()对象,将其打开,然后conn超出范围。这里的conn对象是打开的连接。

这是使它生效的最短方法,但是正如评论中所指出的那样,这也不是那么好。我对此进行了布局,以确切地解释您在做什么错/为什么您的工作不起作用。在此下方,我有一个带有using语句的示例。

public class frmManageAppointment : Form {

    SqlConnection conn; //private variable available to all methods in this class

    private void frmManageAppointment_Load(object sender, EventArgs e)
    {
        Connect();
    }

    private void ExitButton_Click(object sender, EventArgs e)
    {
        this.CloseConn(); //new method here
        this.Close();
    }

    void CloseConn() {
        //we want to close/dispose the connection obect
        conn.Close();
        conn.Dispose();
    }


    public void Connect()
    {
        string conString = "<constring>";
        conn = new SqlConnection(conString); //removed type here so conn now the class level variable
        conn.Open();
        //rest of code snipped        
    }

    public Boolean MakeAppointment()
    {
        string sql = "<sql string>"; //btw, the way you're generating this string is ... not ideal.  Google sql injection
        SqlCommand cmd = new SqlCommand(sql, conn); //conn is our global variable, which we're assuming here is still open/valid (not ideal)
        return cmd.ExecuteNonQuery() > 0;
    }

}

问题是您的表单将无限期地打开。如果小型应用程序连接到本地数据库,而该应用程序是唯一的连接对象,那么这可能不会有问题,但是保持连接打开状态会浪费服务器资源,并且您无法保证conn对象在您使用时仍然有效稍后尝试在MakeAppointment()中使用它。您可以添加检查它实际上是打开的,如果没有打开,则再次调用Connect(),但这是一堆徒劳的工作。使用数据库(或任何网络资源)时采用的一种更好的模式/习惯是仅在需要工作时打开它们,并在完成后立即关闭/释放它们。就是说,这就是您的代码的样子。

public class frmManageAppointment : Form {

    //no need for a Connect() method, conn global variable, or a CloseConn() method
    //your other methods pertaining to the UI would need to be copied over

    public Boolean MakeAppointment()
    {
        string sql = "<sql string>"; //again, what you're doing here is bad
        using(SqlConnection conn = new SqlConnection("<connectionstring>") {
            conn.Open();
            using(SqlCommand cmd = new SqlCommand(sql, conn)) {
                return cmd.ExecuteNonQuery() > 0;
            }
        }
    }
}

[您仅在使用连接之前立即打开连接(在此示例中,您要做的唯一工作是在MakeAppointment()中,并且通过将连接和命令包装在using语句中,它们将被自动处置(通过在对象超出范围时调用这些对象Dispose()方法)。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.