如本文所述,我正在使用 C# 将表从 SQL Server 重建到 Access感谢我得到的帮助,我可以完成这个过程,但由于.accdb文件非常大,我需要在之后压缩和修复它们。为此,我使用了此处标记的答案。奇怪的是,只有"Microsoft Office 16.0 Access 数据库引擎对象库"的引用可以添加到我的项目中。
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 来完成此任务,因为我已经在使用它来创建我的目录?
遗憾的是,JRO、ADO 和 ADOX 都不能用于压缩和修复Microsoft访问.accdb(Access 2007 及更高版本(数据库文件。 但是,通过使用 DBEngine 对象,您走在正确的轨道上。 您可以用来避免依赖 PIA 的一种方法是在 ACE DAO 引擎上使用后期绑定(将 JET DAO 引擎替换为较旧的 .mdb 格式(。
此方法不需要 PIA 或项目参考。 但它确实要求在计算机上安装 ACE 引擎。 ACE 可自由分发,可从 Microsoft - Microsoft Access 数据库引擎 2010 可再发行
组件下载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;
}