3

我正在尝试使用 C# 通过 OleDbConnection 在 Access 数据库上执行 SQL 命令,并使用该信息在 Windows 窗体上填充 DataGridView。我已经打开了连接,陈述了查询并执行了它,但是我找不到如何将结果输出到 Windows 窗体上的 DataGridView(名为 dataOutput)。

    private void Query()
    {
        string cmdText = "SELECT * FROM RetentionTable " +
            "WHERE [DateTime] BETWEEN '" + getDateTimeFrom("") + "' AND '" + getDateTimeTo("") + "'";

        string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";

        try
        {
            OleDbConnection cn = new OleDbConnection(ConnectionPath);
            DataSet objDataSet = new DataSet();
            OleDbDataAdapter objDataAdapter = new OleDbDataAdapter();

            if (cn.State.Equals(ConnectionState.Closed))
            {
                cn.Open();
            }

            OleDbCommand OleDbSearch = new OleDbCommand(cmdText, cn);
            OleDbSearch.ExecuteNonQuery();

            objDataAdapter.Fill(objDataSet);
            dataOutput.DataSource = objDataSet;
            cn.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message.ToString());
            MessageBox.Show(ex.StackTrace.ToString());
        }

    }

从我所见,查询正在正确执行,但是在尝试使用 objDataAdapter.Fill 时出现问题。我想我不明白如何用查询的输出填充数据集。任何帮助将非常感激。谢谢!

4

5 回答 5

3

用。。。来代替ExecuteDataSet method

..
OleDbSearch.ExecuteDataSet();
objDataAdapter.Fill(objDataSet);
dataOutput.DataSource = objDataSet;
...

我建议您在使用 blok 或尝试使用 finally of your try catch 中设置您的紧密连接

最佳实践

 using( var cn = new OleDbConnection(ConnectionPath))
 {
    ... 
 }
于 2013-07-17T18:20:27.230 回答
1

几点评论:

  1. 您的查询受到 SQL 注入的影响。请改用参数化查询。
  2. 您不需要打开/关闭连接;DataAdapter会为你做的。
  3. OleDbConnection您应该将和OleDbCommand对象包装在一个using块中,以确保清理它们的资源。
  4. 您不需要调用ExecuteNonQuery, 或命令上的任何其他Execute...方法;
  5. 您需要将命令分配给 的SelectCommand属性OleDbDataAdapter,或将其传递给构造函数。

尝试这样的事情:

private void Query()
{
   const string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";

   try
   {
      using (var cn = new OleDbConnection(ConnectionPath))
      using (var cmd = new OleDbCommand("SELECT * FROM RetentionTable WHERE [DateTime] BETWEEN ? And ?"))
      {
         // Parameter names don't matter; OleDb uses positional parameters.
         cmd.Parameters.AddWithValue("@p0", getDateTimeFrom(""));
         cmd.Parameters.AddWithValue("@p1", getDateTimeTo(""));

         var objDataSet = new DataSet();
         var objDataAdapter = new OleDbDataAdapter(cmd);
         objDataAdapter.Fill(objDataSet);

         dataOutput.DataSource = objDataSet;
      }
   }
   catch (Exception ex)
   {
      MessageBox.Show(ex.Message.ToString());
      MessageBox.Show(ex.StackTrace.ToString());
   }
}
于 2013-07-17T18:29:11.180 回答
0

我认为您还可以将数据加载到 DataTable 并将 DataGridView 指向表:

DataTable dt = new DataTable();
dt.Fill(OleDbSearch.ExecuteReader());
dataOutput.DataSource = dt;
于 2013-07-17T18:22:38.677 回答
0

您不应执行OleDbSearch.ExecuteNonQuery此操作,仅用于修改数据的查询(插入/更新)。而是将您的命令分配给 dataadatper:

objDataAdapter.SelectCommand = OleDbSearch;

然后做你的Fill和 DataSource 分配。

于 2013-07-17T18:22:57.417 回答
0

使用 an 检索 DataSet 的正确方法OleDbDataAdapter是将 与OleDbDataAdapterOleDbCommand的属性相关联。SelectCommand您只需将 OleDbCommand 传递给 OleDbDataAdapter 的构造函数。

此外,您的代码应该对命令文本使用参数化查询,而不是字符串连接。使用参数化查询可以避免 Sql 注入,并且正确解析文本、日期、小数变量由框架代码完成。

   string cmdText = "SELECT * FROM RetentionTable WHERE [DateTime] BETWEEN ? AND ?";
   string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";
   try
   {
        using(OleDbConnection cn = new OleDbConnection(ConnectionPath))
        using(OleDbCommand OleDbSearch = new OleDbCommand(cmdText, cn))
        using(OleDbDataAdapter objDataAdapter = new OleDbDataAdapter(OleDbSearch))
        {
            OleDbSearch.Parameters.AddWithValue("@p1", getDateTimeFrom(""));
            OleDbSearch.Parameters.AddWithValue("@p2", getDateTimeTo(""));
            DataSet objDataSet = new DataSet();
            cn.Open();
            objDataAdapter.Fill(objDataSet);
            dataOutput.DataSource = objDataSet;
        }
    }
    catch (Exception ex)
    {
         MessageBox.Show(ex.Message.ToString());
         MessageBox.Show(ex.StackTrace.ToString());
    }

using 语句是另一个需要注意的地方。这将确保在出现异常时正确关闭和处理连接、命令和适配器。

于 2013-07-17T18:27:00.550 回答