Oracle连接在第二次尝试时不起作用

时间:2014-04-19 19:35:04

标签: c# oracle dbconnection

public void comboboxes()
{
    using (OracleConnection conn = new OracleConnection("Data Source=localhost;Persist Security Info=True;User ID=kursinis1;Password=1234;Unicode=True"))
    {
        try
        {
            conn.Open();
            comboBox1.Items.Clear();
            DataSet dsetas1 = new DataSet();
            OracleDataAdapter data1 = new OracleDataAdapter("select aut_id, (aut_vardas || ' ' || aut_pavarde) AS autorius from autoriai", conn);
            data1.SelectCommand.CommandType = CommandType.Text;
            data1.Fill(dsetas1);
            dsetas1.Dispose();
            data1.Dispose();
            conn.Close();

            comboBox1.DataSource = dsetas1.Tables[0];
            comboBox1.DisplayMember = "autorius";
            comboBox1.ValueMember = "aut_id";

        }
        catch (Exception ex)
        {
            MessageBox.Show("Can not open connection ! ");
        }
    }
}

当我第一次调用函数时,它可以工作(将数据填充到复选框),但是当我尝试再次调用该函数时(通过按钮单击)。它显示我的连接未打开的错误:

Error: Items collection cannot be modified when the DataSource is set.

有什么问题?

2 个答案:

答案 0 :(得分:1)

在使用DataSet绑定到comboBox之前,您正在处置它。数据集的生命周期必须等于comboBox。

您需要使DataSet成为拥有comboBox的类的成员(并在处理类时处置),或者在处理之前将表中的数据复制到另一个表或对象列表中作为类成员DataSet,并改为绑定到该对象。

public partial class MainForm : Form
{
    private DataTable dataTable = new DataTable();

    public MainForm()
    {
        InitializeComponent();

        comboBox1.DataSource = dataTable;
        comboBox1.DisplayMember = "autorius";
        comboBox1.ValueMember = "aut_id";
    }

    public void comboboxes()
    {
        using (OracleConnection conn = new OracleConnection("Data Source=localhost;Persist Security Info=True;User ID=kursinis1;Password=1234;Unicode=True"))
        {
            conn.Open();
            using (OracleDataAdapter data1 = new OracleDataAdapter("select aut_id, (aut_vardas || ' ' || aut_pavarde) AS autorius from autoriai", conn))
            {
                data1.SelectCommand.CommandType = CommandType.Text;
                data1.Fill(dataTable);
            }
        }
    }
}

(未经过测试,但有类似的事情)

答案 1 :(得分:1)

首先,您在使用ComboBox.Items时甚至不需要清除DataBinding属性。

其次,在将结果集绑定到DataSet控件之前,您要处置DataAdapterComboBox

第三,使用using块定义了变量的使用范围,以及它们应自动处理的范围。

我注释掉了您不需要的行,并添加了finally子句,该子句会在try...catch块结束时随时执行。

public void comboboxes() {
    using (OracleConnection conn = new OracleConnection("Data Source=localhost;Persist Security Info=True;User ID=kursinis1;Password=1234;Unicode=True")) {
        try {
            conn.Open();
            //comboBox1.Items.Clear();
            DataSet dsetas1 = new DataSet();
            OracleDataAdapter data1 = new OracleDataAdapter("select aut_id, (aut_vardas || ' ' || aut_pavarde) AS autorius from autoriai", conn);
            data1.SelectCommand.CommandType = CommandType.Text;
            data1.Fill(dsetas1);
            //dsetas1.Dispose();
            //data1.Dispose();
            //conn.Close();

            comboBox1.DataSource = dsetas1.Tables[0];
            comboBox1.DisplayMember = "autorius";
            comboBox1.ValueMember = "aut_id";
        } catch (Exception ex) { MessageBox.Show("Can not open connection ! "); }
        finally {
            if (ConnectionState.Open == conn.State) conn.Close();
        }
    }
}

如果您希望确保DataSetDataAdapter在不再需要时立即处理,请将它们放入using块中。

using (var cnx = new OracleConnection(connectionString)) 
    using (var ds = new DataSet())
        using (var da = new OracleDataAdapter(query)) {
            da.SelectCommand.CommandType = CommandType.Text;

            if (ConnectionState.Closed == cnx.State) cnx.Open();

            da.Fill(ds);

            comboBox1.DataSource = ds.Tables[0];
            comboBox1.DisplayMember = "autorius";
            comboBox1.ValueMember = "aut_id";                                 
        }

全部三个:当您的代码退出using块时,您的连接,数据集和数据适配器将自动处理。

否则,如果您愿意,也可以在try...catch...finally块中围绕连接的开口,并确保无论发生什么情况,您的连接都会被关闭。

此外,最好是让异常在ordre中冒泡你的应用程序以获得完整的堆栈跟踪和正确的异常,以便你获得所有必需的细节来解决你的问题。

优雅处理时会出现try...catch个例外情况。例如,记录日志,然后可能只是简单地重新向您发送GUI,以便您可以使用正确的错误消息等来处理它。