【问题标题】:OleDbDataAdapter: cannot update databaseOleDbDataAdapter:无法更新数据库
【发布时间】:2012-01-22 02:58:14
【问题描述】:

我从昨天开始一直在处理这个问题,但我无法更新我的数据库。 有3张桌子。这是其中一个 WinForms 的一段代码。它加载数据并显示,但在网格中手动更改某事后,我通过调用 Update 得到错误或任何事情发生。

请帮忙,因为我快疯了。

    public partial class Form3 : Form
    {
    //instance fields
    private export2Excel export2XLS;
    private DataSet _dataSet;
    private BindingSource _bsrc;
    private OleDbDataAdapter _dAdapter;
    private OleDbCommandBuilder _cBuilder;
    private DataTable _dTable;

    private void button1_Click(object sender, EventArgs e)
    {
        //create the connection string
        string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data      
        Source='C:\\Documents and Settings\\dorota\\Moje dokumenty\\Visual Studio  
        2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\artb.mdb'";

        //create the database query
        string query = "SELECT * FROM Samochody";
        System.Data.DataSet DtSet = new System.Data.DataSet();
        _dataSet = DtSet;
        //create an OleDbDataAdapter to execute the query
        OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
        dAdapter.FillSchema(_dataSet, SchemaType.Source);

        _dAdapter = dAdapter;
        //create a command builder
        OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(_dAdapter);
        _cBuilder = cBuilder;
        //create a DataTable to hold the query results
        DataTable dTable = new DataTable();
        _dTable = dTable;
        //fill the DataTable
        _dAdapter.Fill(_dTable);
        //_dAdapter.TableMappings.Add("Samochody", "Table");

        _dAdapter.Fill(_dataSet);

        // --------------------- to datagridview !

        //BindingSource to sync DataTable and DataGridView
        BindingSource _bsrc = new BindingSource();

        //set the BindingSource DataSource
        //bSource.DataSource = _dTable;
        _bsrc.DataSource = _dTable;
        //_bsrc = bSource;
        //set the DataGridView DataSource
        dataGridView1.DataSource = _bsrc;
    }
    }

这里……:

    private void sqlsave_Click(object sender, EventArgs e)
    {

        //int i=_dAdapter.Update(_dTable);
        _dAdapter.Update(_dataSet.Tables["Samochody"]);
        //_dAdapter.Update(_dataSet,"Samochody");
    }

//--------------------------------------------- ------------------------------------

好的。我为此更改了 sqlsave 方法

    private void sqlsave_Click(object sender, EventArgs e)
    {

    try
    {
        //_dAdapter.Update(_dataSet.Tables["Samochody"]);
         OleDbCommand oldb= _cBuilder.GetUpdateCommand();
         int i=oldb.ExecuteNonQuery();
         System.Windows.Forms.MessageBox.Show(i+" rows affected.");
        //_dAdapter.Update(_dataSet,"Samochody");
    }catch(OleDbException oldbex){
        System.Windows.Forms.MessageBox.Show(oldbex.ToString());
    }

现在我终于得到了比“错误”更多的信息

“System.InvalidOperationException”类型的未处理异常 发生在 System.Data.dll 附加信息:ExecuteNonQuery 需要一个开放且可用的连接。连接的电流 状态已关闭。

所以让我改变一下,如果是这样,我会告诉你的!

//--------------------------------

没有。不。太快了,坚持不下去了。现在在尝试保存时,我又遇到了异常, connectin 已打开,但是(我无法发布图像)当我调试它时,我看到我的 OleDbCommand 类型为 _commandText 的对象有

“UPDATE Samochody SET Item=?, Datadyspozycji autem od=?, ...”

等等。 我想这就是原因。我对吗?怎么办?

【问题讨论】:

  • 您正在混合和匹配不同的方法。 ExecuteNonQuery 需要一个开放的连接——CommandBuilder 不会为您提供。您需要将 Update 命令放入 DataAdapter 并运行 Update。您可能必须提供自己的更新方法。确保您的表具有 PrimaryKey 索引。
  • @LarsTech 您说过“将更新命令放入 DataAdapter”。如果我在我的 _cBuilder 上进行更新,它是此类中的私有字段并由 button1_Click 命令中的 _dAdapter 初始化,这不是可以吗?连接已打开。在 sqlsave_Click() 我有:

标签: c# winforms oledbdataadapter


【解决方案1】:

您没有为您的OleDbDataAdapter 提供连接。试试这样的:

该示例与您的代码不同,但它显示了 New Connection 的声明并将其传递给 OleDbDataAdapter

        string connetionString = null;
        OleDbConnection connection ;
        OleDbDataAdapter oledbAdapter ;
        OleDbCommandBuilder oledbCmdBuilder ;
        DataSet ds = new DataSet();
        int i = 0;
        string sql = null;
        connetionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Your mdb filename;";
        connection = new OleDbConnection(connetionString);
        sql = "select * from tblUsers";
        try
        {
            connection.Open();  // your code must have like this
            oledbAdapter = new OleDbDataAdapter(sql, connection);
            oledbCmdBuilder = new OleDbCommandBuilder(oledbAdapter);
            oledbAdapter.Fill(ds);
            for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
            {
                ds.Tables[0].Rows[i].ItemArray[2] = "neweamil@email.com";
            }
            oledbAdapter.Update(ds.Tables[0]);
            connection.Close();
            MessageBox.Show ("Email address updates !");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

【讨论】:

  • 我有一个连接 `OleDbCommand oldb= _cBuilder.GetUpdateCommand(); oldb.Connection.Open(); int i=oldb.ExecuteNonQuery(); System.Windows.Forms.MessageBox.Show(i+" 受影响的行。"); //_dAdapter.Update(_dataSet,"Samochody"); oldb.Connection.Close(); }catch(OleDbException oldbex){ System.Windows.Forms.MessageBox.Show(oldbex.ToString()); }`
  • _cBuilder 与 Ole Objects 的其余部分一样存储在该类的私有字段中,请看主要代码的顶部。我希望如果我存储这个在其他点击方法中初始化的对象是可以的(?)如果我想影响来自同一个 Windows 窗体的不同功能的相同数据,我不必每次都创建新的 aAdapter、BindingSource 等 -我呢?
【解决方案2】:

我找到了答案:

但更好的方法是使用拖放并从代码中学习。

Select Data|View Datasources. Your dataset should be visible in the DataSources Window.
Drag a table to a (new) form. VS2005 will add a load of components and a few lines of code.

表单现在将有一个数据集实例,这是您的 Adapter.Fill 和 .Update 方法的参考点。

简单而且效果很好! :D
我在这里找到了它:https://stackoverflow.com/a/548124/1141471

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多