1

所以我有一个textbox和一个button。我想在其中输入一个值,它会从被调用的“票证”textbox中找到我在其中输入的值。然后我还想在一个名为“Rebateslip”的文件中创建一个“rebateslip”。这有 2 个字段 - 一个是自动递增的,一个是我在其中输入的值(所以基本上我只是将我刚刚找到的值传递到“RebateSlip”表中)。我将所有函数放在一个名为“模型”中,然后在事件处理程序中调用它们。rowtableobjecttabletableidticketIdtextboxticketIdclassbutton

 public bool rebateslip(int ticketID)
    {
        SqlCommand myCommand = new SqlCommand("SELECT ID FROM ticket WHERE ID = @ticketID", con);
        SqlDataAdapter sqlDa = new SqlDataAdapter(myCommand);

        myCommand.Parameters.AddWithValue("@ticketID", ticketID);
        var reader = myCommand.ExecuteReader();
        return reader.HasRows;

    }

    public void createRebateslip(int ticketId)
    {
        SqlCommand myCommand = new SqlCommand("INSERT INTO RebateSlip (ticketId) VALUES (@ticketId); SELECT SCOPE_IDENTITY();", con);
        myCommand.Parameters.AddWithValue("@ticketId", ticketId);
        string insertID = (myCommand.ExecuteScalar()).ToString();
        rebateSlipList.Add(new RebateSlip(Int32.Parse(insertID), ticketId));
    }

它适用于一个数字,但如果我尝试在其中输入另一个数字,textbox则会收到错误消息,已经有一个DataReader与命令关联的打开,必须先关闭。这是按钮的代码。如果在表中找到该值,则应创建一个“rebatelip”,但这也不起作用。

 private void buttonPrintRebateSlip_Click(object sender, EventArgs e)
    {

        int id;
        if (!int.TryParse(textBoxRebateSlip.Text, out id))
        {
            return;
        }
        if (model.rebateslip(id))
        {
            MessageBox.Show("Found ticket");
            //create rebate slip object
            model.createRebateslip(id);
            textBoxRebateSlip.Clear();
        }
        else
        {
            MessageBox.Show("Ticket not in database");
            textBoxRebateSlip.Clear();
        }

    }
4

3 回答 3

2

SqlDataReader.Close 方法的摘录:

当您通过使用 SqlDataReader 以将关联的 SqlConnection 用于任何其他目的时,您必须显式调用 Close 方法。

你应该使用using Statement.

public bool rebateslip(int ticketID)
{
    using(SqlCommand myCommand = new SqlCommand("SELECT ID FROM ticket WHERE ID = @ticketID", con))
    {
        using(SqlDataAdapter sqlDa = new SqlDataAdapter(myCommand))
        {

            myCommand.Parameters.AddWithValue("@ticketID", ticketID);
            using(var reader = myCommand.ExecuteReader())
            {
                return reader.HasRows;
            } 
        }
    }
}

无论如何,您的sqlDaSqlDataAdapter 在上下文中毫无意义。可能你只需要:

public bool rebateslip(int ticketID)
{
    using(SqlCommand myCommand = new SqlCommand("SELECT ID FROM ticket WHERE ID = @ticketID", con))
    {
        myCommand.Parameters.AddWithValue("@ticketID", ticketID);
        using(var reader = myCommand.ExecuteReader())
        {
            return reader.HasRows;
        }
    }
}
于 2013-01-31T18:22:13.397 回答
0

reader.close一旦你完成它。

另外——你应该使用 a usingortry...catch

于 2013-01-31T18:23:34.500 回答
0

这样你就永远不会有一个 reader 变量。仍然使用范例更好。

    public bool rebateslip(int ticketID)
    {
        SqlCommand myCommand = new SqlCommand("SELECT ID FROM ticket WHERE ID = @ticketID", con);
        SqlDataAdapter sqlDa = new SqlDataAdapter(myCommand);

        myCommand.Parameters.AddWithValue("@ticketID", ticketID);
        return myCommand.ExecuteReader().HasRows;
    }

    public void createRebateslip(int ticketId)
    {
        SqlCommand myCommand = new SqlCommand("INSERT INTO RebateSlip (ticketId) VALUES (@ticketId); SELECT SCOPE_IDENTITY();", con);
        myCommand.Parameters.AddWithValue("@ticketId", ticketId);
        int insertID = (int)myCommand.ExecuteScalar();
        rebateSlipList.Add(new RebateSlip(insertID, ticketId));
    }

此外,您似乎将ticketID 存储在Insert 表中(来自insertID),而insertID 存储在Ticket 表中(来自ticketID)。相反,您应该使用仅存储 insertID 和 ticketID 的第三个表,允许多对多关系,同时允许通过单个操作更改/删除它们。

于 2013-01-31T18:38:52.590 回答