2013-11-28 2 views
1

У меня есть база данных доступа, содержащая таблицу под названием «Элементы». У меня есть несколько небольших баз данных, которые также содержат таблицу «Элементы». Каждый из них имеет первичный ключ с именем «ID», и дубликатов нет.Невозможно записать изменения в базу данных доступа после слияния таблицы

Следующий код появляется успешно объединить (если ставить точки останова до и после слияния dsi.Tables («Items»). Rows.Count увеличивается, но фактическая база не изменилась.

Помощь !!

Благодаря Энди

Imports System.Data 
Imports System.Data.OleDb 

Public Class Form1 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load 

     Dim dsicmd, dsacmd As OleDbDataAdapter 
     Dim dsi, dsa, dsc As New DataSet 
     Dim strSelect As String 
     Dim strConnection As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\TEMP\data\Account Data.mdb" 
     Dim strC2 As String 
     Dim cn, cn2 As OleDbConnection 
     Dim cmd As OleDbCommandBuilder   

     ' ** Items   
     cn = New OleDbConnection(strConnection) 
     cn.Open() 
     strSelect = "SELECT * FROM Items" 
     dsicmd = New OleDbDataAdapter(strSelect, cn) 
     dsicmd.Fill(dsi, "Items")   

     For Each f In My.Computer.FileSystem.GetFiles("d:\temp\data", FileIO.SearchOption.SearchTopLevelOnly, "*.mdb") 
      If Not f.Contains("Account") Then 
       strC2 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & f 
       cn2 = New OleDbConnection(strC2) 
       cn2.Open() 
       strSelect = "SELECT * FROM Items" 
       dsacmd = New OleDbDataAdapter(strSelect, cn2) 
       dsa.Clear() 
       dsacmd.Fill(dsa, "Items") 

       dsi.Merge(dsa, False, MissingSchemaAction.Add)         

       dsa.Dispose() 
       cn2.Close() 
      End If 
     Next 

     cmd = New OleDbCommandBuilder(dsicmd) 
     dsicmd.UpdateCommand = cmd.GetUpdateCommand 
     dsicmd.InsertCommand = cmd.GetInsertCommand 
     dsicmd.Update(dsi, "Items") 

     cn.Close() 
     dsi.Dispose()   
     dsc.Dispose() 
     dsicmd.Dispose() 
     dsacmd.Dispose() 
     cn.Dispose() 
     cn2.Dispose() 

    End Sub 
End Class 
+0

Почему вы используете False в этом утверждении: 'dsi.Merge (dsa, False, MissingSchemaAction.Add)' – cha

+0

Привет! Я использовал False, поскольку это было в примере, который я нашел в MSDN. Я тоже пробовал Истину, и это не имеет никакого значения. –

+0

Я думаю, вам нужно вызвать 'dsi.AcceptChanges()' вместо всех этих строк: 'CMD = Новый OleDbCommandBuilder (dsicmd) dsicmd.UpdateCommand = cmd.GetUpdateCommand dsicmd.InsertCommand = cmd.GetInsertCommand dsicmd.Update (DSI , "Элементы") ' – cha

ответ

0

Ваши обновления не получают записываются обратно в основной базе данных, потому что, когда вы делаете .Merge новые строки добавляются в DataTable с их текущей .RowStatus в другом DataTable, который равен Unchanged. Таким образом, когда вы вызываете метод .Update, основной DataTable имеет больше строк, чем раньше, но все они отмечены как Unchanged, поэтому OleDbDataAdapter предполагает, что ему нечего делать.

Вместо этого вам необходимо установить .Add новые DataRows на основной DataTable, чтобы их статус был Added, когда имеет место .Update. Следующий код работает для меня. (. Это C# код, но это не должно быть слишком трудно сопоставить его обратно в VB.NET)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.OleDb; 

namespace mergeTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (OleDbConnection conExisting = new OleDbConnection()) 
      { 
       conExisting.ConnectionString = 
         @"Provider=Microsoft.Jet.OLEDB.4.0;" + 
         @"Data Source=C:\__tmp\data\existingStuff.mdb;"; 
       conExisting.Open(); 
       using (OleDbDataAdapter daExisting = new OleDbDataAdapter()) 
       { 
        daExisting.SelectCommand = new OleDbCommand(); 
        daExisting.SelectCommand.Connection = conExisting; 
        daExisting.SelectCommand.CommandText = "SELECT * FROM Items"; 
        var dtExisting = new System.Data.DataTable(); 
        daExisting.Fill(dtExisting); 
        Console.WriteLine(string.Format("dtExisting has {0} rows", dtExisting.Rows.Count)); 
        using (OleDbConnection conNew = new OleDbConnection()) 
        { 
         conNew.ConnectionString = 
           @"Provider=Microsoft.Jet.OLEDB.4.0;" + 
           @"Data Source=C:\__tmp\data\newStuff.mdb;"; 
         conNew.Open(); 
         using (OleDbDataAdapter daNew = new OleDbDataAdapter()) 
         { 
          daNew.SelectCommand = new OleDbCommand(); 
          daNew.SelectCommand.Connection = conNew; 
          daNew.SelectCommand.CommandText = "SELECT * FROM Items"; 
          var dtNew = new System.Data.DataTable(); 
          daNew.Fill(dtNew); 
          foreach (System.Data.DataRow drNew in dtNew.Rows) 
          { 
           System.Data.DataRow drExisting = dtExisting.NewRow(); 
           drExisting.ItemArray = drNew.ItemArray; // copy columns 
           dtExisting.Rows.Add(drExisting); 
          } 
          Console.WriteLine(string.Format("dtExisting now has {0} rows:", dtExisting.Rows.Count)); 
          foreach (System.Data.DataRow dr in dtExisting.Rows) 
          { 
           Console.WriteLine(String.Format("ID={0}, RowState={1}", dr["ID"], dr.RowState)); 
          } 
         } 
         conNew.Close(); 
        } 
        OleDbCommandBuilder cbExisting = new OleDbCommandBuilder(daExisting); 
        cbExisting.QuotePrefix = "["; 
        cbExisting.QuoteSuffix = "]"; 
        daExisting.Update(dtExisting); 
       } 
       conExisting.Close(); 
      } 
      Console.WriteLine(); 
      Console.WriteLine("Done."); 
      Console.ReadKey(); 
     } 
    } 
} 

Используя мои тестовые данные, выход консоли:

dtExisting has 3 rows 
dtExisting now has 6 rows: 
ID=existing1, RowState=Unchanged 
ID=existing2, RowState=Unchanged 
ID=existing3, RowState=Unchanged 
ID=new1, RowState=Added 
ID=new2, RowState=Added 
ID=new3, RowState=Added 

Done. 
+0

Спасибо. В итоге я понял то же самое и использовал аналогичный код, который использовал ImportRow, а затем DataRow.SetAdded в фиктивную таблицу, а затем использовал GetChanges и Update. –

Смежные вопросы