2016-03-07 29 views
0

使用外部C#应用程序在一个空的MS Access表中插入记录时,我有一个奇怪的现象插入后正确地刷新MS Access表不与C#的ExecuteNonQuery

我的过程是:

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

所以,问题是,该表没有插入

后,这是我的代码中访问

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”,我看到数据。然后,关闭表格并恢复(继续)访问代码执行,现在找到记录并且代码运行平稳。

插入记录(在这个例子中,只有一条记录)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中,可能是什么问题呢?有没有办法在阅读之前强制访问刷新或更新表格?我试图在movefirst之前关闭并重新打开表,在执行shell之后插入DoEvents ...没有任何工作:(

在c#中,代码有问题吗?是否需要更改连接字符串中的某些内容,或者命令或事务强制更新表格?

+0

也许尝试一个dbf.TableDefs.Refresh就在您设置dbf = ...但不确定... –

+0

行:“INSERT INTO MyTable([Field1],[Field2])”+“VALUES(@ Param1 ,@Param2)“;基本上与“INSERT INTO MyTable([Field1],[Field2])VALUES(@Param1,@ Param2)”相同。你确定语法正确吗?最好的问候, –

+0

为什么你只用一个插入命令使用Transaction?那么这两个操作的准确时间是什么?一个在C#中,另一个在Access中呢?最好的问候, –

回答

2

问题不在于ac#代码问题,只是Access会话尚未意识到由外部进程添加的新记录。 INSERT from 任何外部过程都可能发生同样的情况。我用VBScript文件替代了UpdateTable.exe

此访问VBA代码触发错误3021,“没有当前记录”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线,使新添加的记录在当前访问会话立即可用,所以记录集MoveFirst方法不会触发错误。

+0

谢谢!它的作品完美!:) – Kaikus

+0

哇!我忘了标记你的完美解决方案作为答案...对不起:( – Kaikus