ms访问数据库和c#:不能再打开表

本文关键字:不能 访问 数据库 ms | 更新日期: 2023-09-27 18:05:11

我已经连接了我的访问数据库到我的c#项目。我有1760行在我的数据库,当我试图打印这些行在我的c#项目的datagridview它给了我一个错误,说程序不能再打开表。而且,它不会一直给出这个错误。有时它运行正常,没有任何错误。我已经搜索并寻求帮助来解决这个问题,但我到了一个死胡同,我甚至不明白为什么它给这个错误;我已经调试和检查代码一千次了,但还是没有发现问题。

我已经把我的程序代码和错误信息的截图。

edataGridView1.Rows.Clear();
        OleDbConnection c = new OleDbConnection();
        c.ConnectionString = "Provider=Microsoft.Ace.Oledb.12.0;Data Source=" + Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "''Database.accdb";
        using (OleDbCommand cmd = new OleDbCommand(" SELECT * from omed", c))
        {
            c.Open();
            OleDbDataReader Reader = cmd.ExecuteReader();
            while (Reader.Read())
            {
                DataGridViewRow row = new DataGridViewRow();
                row.CreateCells(dataGridView1);  // this line was missing
                row.Cells[0].Value = Reader["ID"].ToString();
                row.Cells[1].Value = Reader["CELL"].ToString();
                row.Cells[2].Value = Reader["ncc"].ToString();
                row.Cells[3].Value = Reader["bcchno"].ToString();
                dataGridView1.Rows.Add(row);
                for (int i = 0; i < 31; i++)
                {
                    row.Cells[i * 3 + 4].Value = Reader["n_cell_" + i].ToString();
                    using (OleDbCommand cmd0 = new OleDbCommand(" SELECT * from omed  WHERE CELL  LIKE '" + Reader["n_cell_" + i].ToString() + "'", c))
                    {
                        OleDbDataReader Reader0 = cmd0.ExecuteReader();
                        int counter = 0;
                        while (Reader0.Read())
                        {
                            row.Cells[i * 3 + 5].Value = Reader0["ncc"].ToString();
                            row.Cells[i * 3 + 6].Value = Reader0["bcchno"].ToString();
                        }
                    }
                }
            }
       }
        c.Close();

ms访问数据库和c#:不能再打开表

在该循环中关闭阅读器,我认为垃圾收集器有时会跟上它,有时不会:

...
OleDbDataReader Reader0 = cmd0.ExecuteReader();
int counter = 0;
while (Reader0.Read())
{
    row.Cells[i * 3 + 5].Value = Reader0["ncc"].ToString();
    row.Cells[i * 3 + 6].Value = Reader0["bcchno"].ToString();
}
Reader0.Close();
...

好像使用access作为'数据库'还不够,您在同一连接上使用(实际上不必要的)多个读取器。在同一连接上使用多个读取器本身就是一个严重的问题。

第二,你根本不需要那个。您在第一次调用中选择了'omed'中的所有行,您不需要往返数据库以从您已经有结果的同一源进行更多选择。

第三,您的内部读取器循环实际上只使用不必要的第二次调用检索到的最后一行,因此while(Reader0.Read())是多余的。

修改后的代码看起来像这样:

edataGridView1.Rows.Clear ();

DataTable tbl = new DataTable();
using(OleDbConnection c = new OleDbConnection())
using (OleDbCommand cmd = new OleDbCommand("SELECT * from omed", c))
{
  c.ConnectionString = "Provider=Microsoft.Ace.Oledb.12.0;Data Source=" + 
     Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "''Database.accdb";
  c.Open();
  OleDbDataReader reader = cmd.ExecuteReader();
  tbl.Load(reader);
  c.Close();
}
foreach (DataRow r in tbl.Rows)
{
    DataGridViewRow row = new DataGridViewRow();
    row.CreateCells(dataGridView1);  // this line was missing
    row.Cells[0].Value = r["ID"].ToString();
    row.Cells[1].Value = r["CELL"].ToString();
    row.Cells[2].Value = r["ncc"].ToString();
    row.Cells[3].Value = r["bcchno"].ToString();
    dataGridView1.Rows.Add(row);
    for (int i = 0; i < 31; i++)
    {
        var v = r["n_cell_" + i].ToString();
        row.Cells[i * 3 + 4].Value = v; 
        var resultRow = tbl.AsEnumerable().Last (t => t.Field<string>("CELL").Contains(v));
        row.Cells[i * 3 + 5].Value = resultRow["ncc"].ToString();
        row.Cells[i * 3 + 6].Value = resultRow["bcchno"].ToString();
    }
}