Question

I have an access database containing a table called 'Items'. I have a number of smaller databases that also contain a table 'Items'. They each have a primary key called 'ID' and there are no duplicates.

The following code appears to merge successfully (if I put breakpoints before and after the merge dsi.Tables("Items").Rows.Count increases but the actual database is not changed.

Help!!

Thanks Andy

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
Was it helpful?

Solution

Your updates are not getting written back to the main database because when you do the .Merge the new rows are added to the DataTable with their current .RowStatus in the other DataTable, which is Unchanged. So, when you call the .Update method the main DataTable has more rows than it did before, but they are all flagged as Unchanged so the OleDbDataAdapter assumes that it has nothing to do.

Instead, you need to .Add the new DataRows to the main DataTable so their status will be Added when the .Update takes place. The following code works for me. (It's C# code, but it shouldn't be too difficult to map it back to 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();
        }
    }
}

Using my test data, the console output is:

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top