C# Сжатие и восстановление.accdb файлов с использованием DAO или ADOX

Как указано здесь, я перестраиваю таблицы из SQL Server в Access с помощью C#. Благодаря полученной помощи я смог завершить процесс, но, поскольку файлы.accdb довольно большие, мне нужно их сжать и восстановить. Для этого я использовал отмеченный ответ отсюда. Странно, но я мог добавить в свой проект только ссылку на "Библиотеку объектов ядра СУБД Microsoft Office 16.0".

using Microsoft.Office.Interop.Access.Dao;

var engine = new DBEngine(); // Exception
var destFile = Path.GetFileNameWithoutExtension(filepath) + "_Compact" + ".accdb";
var destFilePath = Path.Combine(Path.GetDirectoryName(filepath), destFile);

engine.CompactDatabase(filepath, destFilePath);

При инициализации DBEngine - Object выдается исключение:

Retrieving the COM class factory for component with CLSID {CD7791B9-43FD-42C5-AE42-8DD2811F0419} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

Кроме того, есть ли способ использовать ADOX для этой задачи, так как я уже использую его для создания своих каталогов?

1 ответ

К сожалению, JRO, ADO или ADOX могут использоваться для сжатия и восстановления файла базы данных Microsoft Access .accdb (Access 2007 и выше). Тем не менее, вы находитесь на правильном пути, используя объект DBEngine. Один из методов, который вы можете использовать, чтобы не полагаться на PIA, - это использовать позднее связывание с механизмом ACE DAO (который заменил механизм JET DAO для более старого формата.mdb).

Этот метод не требует ссылок PIA или Project. Но для этого требуется, чтобы на машине был установлен двигатель ACE. ACE свободно распространяется и может быть загружен с Microsoft - Microsoft Access Database Engine 2010 Redistributable

using System;

// Use ACE DAO to Compact an Access .ACCDB file
// This method uses late binding to create the ACE DAO.DBEngine object
public bool CompactDatabaseACE(string SourceDb, string TempPath)
{
    string Temp1Db, Temp2Db;
    object[] oParams;
    bool retVal = false;

    Temp1Db = Path.Combine(TempPath, Path.GetFileNameWithoutExtension(SourceDb) + ".cmp");
    Temp2Db = Path.Combine(Path.GetDirectoryName(SourceDb),Path.GetFileNameWithoutExtension(SourceDb) + ".old");
    if (File.Exists(Temp1Db))
        File.Delete(Temp1Db);
    if (File.Exists(Temp2Db))
        File.Delete(Temp2Db);
    oParams = new object[]
    {
        SourceDb, Temp1Db
    };
    try
    {
        object DBE = Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DBEngine.120"));
        DBE.GetType().InvokeMember("CompactDatabase", System.Reflection.BindingFlags.InvokeMethod, null, DBE, oParams);
        if (File.Exists(Temp1Db))
        {
            try
            {
                File.Move(SourceDb, Temp2Db);
            }
            catch { }
            if (File.Exists(Temp2Db))
            {
                try
                {
                    File.Move(Temp1Db, SourceDb);
                }
                catch { }
                if (File.Exists(SourceDb))
                {
                    retVal = true;
                }
            }
            if (File.Exists(Temp1Db))
                File.Delete(Temp1Db);
            if (File.Exists(Temp2Db))
                File.Delete(Temp2Db);
        }
        System.Runtime.InteropServices.Marshal.ReleaseComObject(DBE);
        DBE = null;
    }
    catch (Exception ex)
    {
        // Do something with the error
    }
    return retVal;
}
Другие вопросы по тегам