Обновлять связанные таблицы в базе данных MS Access с помощью C # программно - PullRequest
4 голосов
/ 09 марта 2009

У меня есть две базы данных Access 2003 (fooDb и barDb). В fooDb есть четыре таблицы, которые связаны с таблицами в barDb.

Два вопроса:

  • Как обновить содержимое таблицы (связанные таблицы в fooDb должны быть синхронизированы с содержимым таблицы в barDb)
  • Как связать таблицу с другим barDb, используя ADO.NET

Я гуглил, но не получил никаких полезных результатов. Я выяснил, как это сделать в VB (6) и DAO, но мне нужно решение для C #.

Ответы [ 2 ]

5 голосов
/ 06 декабря 2010

Вот мое решение для перекомпоновки таблиц DAO с использованием C #.

Мое приложение использует центральную базу данных MS Access и 8 реальных баз данных, которые связаны между собой. Центральная база данных хранится локально в моем приложении C #, но приложение позволяет расположить 8 баз данных в другом месте. При запуске мое приложение C # повторно связывает таблицы DAO в центральной базе данных на основе настроек app.config.

Кроме того, эта структура базы данных является результатом того, что мое приложение изначально было приложением MS Access, которое я портировал на VB6. В настоящее время я конвертирую свое приложение в C #. Я мог бы отказаться от MS Access в VB6 или C #, но это очень простое решение для настольных БД.

В центральной базе данных я создал таблицу с именами связанных таблиц с тремя столбцами TableName, LinkedTableName и DatabaseName.

При запуске приложения я называю эту процедуру

            Common.RelinkDAOTables(Properties.Settings.Default.DRC_Data
                              , Properties.Settings.Default.DRC_LinkedTables
                              , "SELECT * FROM LinkedTables");

Default.DRC_Data - текущая папка БД центрального доступа Default.DRC_LinkedTables - текущая папка из 8 баз данных

Вот код, который выполняет фактическую перекомпоновку таблиц DAO в C #

        public static void RelinkDAOTables(string MDBfile, string filepath, string sql)
    {
        DataTable linkedTables = TableFromMDB(MDBfile, sql);

        dao.DBEngine DBE = new dao.DBEngine();
        dao.Database DB = DBE.OpenDatabase(MDBfile, false, false, "");
        foreach (DataRow row in linkedTables.Rows)
        {
            dao.TableDef table = DB.TableDefs[row["Name"].ToString()];
            table.Connect = string.Format(";DATABASE={0}{1} ;TABLE={2}", filepath, row["database"], row["LinkedName"]);
            table.RefreshLink();
        }


    }

Дополнительный код, написанный для извлечения данных из базы данных доступа и возврата их в виде DataTable

        public static DataTable TableFromOleDB(string Connectstring, string Sql)
    {
        try
        {
            OleDbConnection conn = new OleDbConnection(Connectstring);
            conn.Open();
            OleDbCommand cmd = new OleDbCommand(Sql, conn);
            OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
            DataTable table = new DataTable();
            adapter.Fill(table);

            return table;
        }
        catch (OleDbException)
        {
            return null;
        }
    }
    public static DataTable TableFromMDB(string MDBfile, string Sql)
    {
        return TableFromOleDB(string.Format(sConnectionString, MDBfile), Sql);
    }
2 голосов
/ 10 марта 2009

Если вы пишете код на C #, то Access не задействован, только Jet. Таким образом, вы можете использовать любой метод доступа к данным, а затем кодировать обновления.

Я много раз кодировал подобные вещи в Access, и мой подход к каждой таблице:

  1. выполнить запрос, удаляющий из fooDB, которого больше нет в barDB.

  2. запустить запрос, который вставляет в записи fooDB, которые в barDB еще не существуют в fooDB.

  3. Я всегда использую код, который пишет на лету SQL, чтобы обновить таблицу fooDB данными из barDB.

Третий - самый сложный. Я перебираю коллекцию полей в DBA и пишу SQL на лету, что-то вроде этого:

UPDATE table2 INNER JOIN table1 ON table2.ID = table1.ID
SET table2.field1=table1.field1
WHERE (table2.field1 & "") <> (table1.field1 & "")

Для числовых полей вам нужно использовать функцию имеющегося у вас диалекта SQL для преобразования нуля в ноль. Запустив Jet SQL, я бы, конечно, использовал Nz (), но через ODBC это не работает. Не уверен, что он будет работать с OLEDB.

В любом случае, смысл состоит в том, чтобы выпустить кучу обновлений SQL по столбцам вместо попыток делать это построчно, что будет гораздо менее эффективно.

...