2016-03-07 73 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