使用 c# ExecuteNonQuery 插入后,MS Access table 无法正确刷新

MS Access table not refreshing correctly after inserting with c# ExecuteNonQuery

使用外部 C# 应用程序在空的 MS Access table 中插入记录时出现奇怪的行为

我的流程是:

  1. 我从 Access 内部使用 WshShell 对象执行 c# 控制台应用程序,'waitOnReturn',因此访问会一直等到 shell 结束。
  2. c#只是连接数据库,执行一个非查询的oledb命令
  3. 当 Access 在 shell 结束后恢复时,我尝试读取新记录,但出现错误:没有记录!。但是,如果我手动打开更新后的 table,记录就在那里!

所以,问题是 table 在插入

后没有更新

这是我在 Access 中的代码

Dim wsh As Object
Dim waitOnReturn As Boolean
Dim errorCode As Integer

Set wsh = CreateObject("WScript.Shell")
waitOnReturn = True
errorCode = wsh.Run("UpdateTable.exe", vbMaximizedFocus, waitOnReturn)

If errorCode <> 0 Then GoTo Error:

Dim dbf As DAO.Database
Dim UpdatedTable As DAO.Recordset

Set dbf = CurrentDb
Set UpdatedTable = dbf.OpenRecordset("MyTable", dbOpenTable)
UpdatedTable.MoveFirst   'ERROR! No records found

但是记录已经插入!他们在那里!事实上,当我收到错误时,Access 会停止并进入调试模式。这时我手动打开"MyTable",看到了数据。然后,我关闭 table,并恢复(继续)执行 Access 代码,现在找到了记录并且代码运行顺利。

插入记录(本例中只有一条记录)的c#代码是这样的:

string connectionString = "Provider=Microsoft.JET.OLEDB.4.0;data source=" + pathToMyDB;
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
    connection.Open();
    OleDbCommand command = connection.CreateCommand();
    command.CommandText = "INSERT INTO MyTable ([Field1], [Field2])" + " VALUES (@Param1, @Param2)";
    command.Parameters.Add("@Param1", OleDbType.WChar, 35);
    command.Parameters.Add("@Param2", OleDbType.Date);
    command.Parameters["@Param1"].Value = "my string";
    command.Parameters["@Param2"].Value = DateTime.Now;
    int insertedRowsCount = 0;
    using (OleDbTransaction transaction = connection.BeginTransaction())
    {
        command.Transaction = transaction;
        try
        {
            insertedRowsCount = command.ExecuteNonQuery();
        }
        catch (InvalidOperationException queryExecutionException)
        {
            transaction.Rollback();
            ProcessQueryExecutionExceptions(queryExecutionException);
        }
        if (insertedRowsCount == 1)
        {
            transaction.Commit();
        }
        else
        {
            transaction.Rollback();
        }
    }
    command.Parameters.Clear();
    connection.Close();
}

在 Access 中,可能是什么问题?有没有办法在阅读之前强制访问刷新或更新 table ?我试图在 movefirst 之前关闭并重新打开 table,在 shell 执行之后插入 DoEvents... 没有任何效果:(

在c#中,代码有问题吗?我是否必须更改连接字符串、命令或事务中的某些内容以强制更新 table?

这个问题并不是真正的 c# 代码问题。只是 Access 会话还不知道外部进程添加的新记录。来自 any 外部进程的 INSERT 也会发生同样的事情。我用替换 UpdateTable.exe

的 VBScript 文件重现了这个问题

此访问 VBA 代码触发错误 3021,"No current record"UpdatedTable.MoveFirst ...

Dim dbf As DAO.Database
Dim UpdatedTable As DAO.Recordset
Dim wsh As Object
Dim waitOnReturn As Boolean
Dim errorCode As Integer

Set wsh = CreateObject("WScript.Shell")
waitOnReturn = True
errorCode = wsh.Run("C:\Windows\SysWOW64\cscript.exe C:\share\Access\vbscript\AdoInsert.vbs", vbMaximizedFocus, waitOnReturn)

'CreateObject("JRO.JetEngine").RefreshCache CurrentProject.Connection
Set dbf = CurrentDb
Set UpdatedTable = dbf.OpenRecordset("tblKaikus", dbOpenTable)
UpdatedTable.MoveFirst ' without RefreshCache -> ERROR 3021, "No current record."

启用 CreateObject("JRO.JetEngine").RefreshCache 行使新添加的记录在当前 Access 会话中立即可用,因此记录集 MoveFirst 方法不会触发错误。