C# 使用 DAO 或 ADOX 压缩和修复 .accdb 文件
Posted
技术标签:
【中文标题】C# 使用 DAO 或 ADOX 压缩和修复 .accdb 文件【英文标题】:C# Compact and repair .accdb files using DAO or ADOX 【发布时间】:2018-05-01 09:04:02 【问题描述】:如here 所述,我正在使用 C# 将表从 SQL Server 重建到 Access 感谢我收到的帮助,我可以完成这个过程,但由于 .accdb 文件非常大,我需要在之后压缩和修复它们。 为此,我使用了the marked answer from here。奇怪的是,我只能将“Microsoft Office 16.0 Access Database Engine Object Library”的引用添加到我的项目中。
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 来完成这项任务,因为我已经在使用它来创建我的目录?
【问题讨论】:
尝试使用后期绑定创建数据库引擎对象:using System.Reflection;
和Object engine= Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DBENGINE.36"));
@ErikvonAsmuth 感谢您的回复。我如何调用方法“CompactDatabase”,因为编译器声明该方法没有定义?
啊,你可以通过使用 Dynamic
类型来解决这个问题(更像是一个 vb 家伙,这些东西在没有它的情况下也能正常工作):Dynamic engine= Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DBENGINE.36"));
非常感谢。对于有同样问题的其他人可能很重要:方法GetTypeFromProgID()
的参数区分大小写。 Dynamic engine= Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DBEngine.36"));
帮了我的忙。
【参考方案1】:
很遗憾,JRO、ADO 和 ADOX 都不能用于压缩和修复 Microsoft Access .accdb(Access 2007 及更高版本)数据库文件。但是,通过使用 DBEngine 对象,您走在了正确的轨道上。您可以用来避免依赖 PIA 的一种方法是在 ACE DAO 引擎上使用后期绑定(它取代了旧的 .mdb 格式的 JET DAO 引擎)。
此方法不需要 PIA 或项目参考。但它确实需要在机器上安装 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;
【讨论】:
是否需要在每台要使用该程序的机器上安装 ACE? 是的,如果它不存在的话。如果安装了 Microsoft Office,那么 ACE 很可能已经在机器上。 ACE 尚未与 Windows 捆绑在一起。自 Windows XP 以来,JET DAO 已与 Windows 捆绑在一起。以上是关于C# 使用 DAO 或 ADOX 压缩和修复 .accdb 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# ADOX 访问 Access 数据库表的属性?