以编程方式压缩和修复 Access 数据库(使用 C#)






3.84/5 (13投票s)
一种简单的方法,使用 Microsoft Jet 库和 C# COM interop 以压缩和修复 Microsoft Access 数据库文件。示例代码旨在集成到 ASP.NET 网站中。
引言
正如你们中的许多人所知,当数据被删除时,Microsoft Access 数据库不会自动缩小。相反,Access 文件会不断增长,直到用户要求应用程序压缩和修复数据库。(您可以告诉 Access 在最后一个用户关闭数据库时自动压缩和修复,但这并不能解决此处提出的问题。)如果您需要以编程方式管理 Access 文件怎么办?我们公司的软件会将数据写入 Access 文件,并允许用户下载它们。只有一个问题 - 每次我们写入文件时,即使我们首先截断表,它也会不断增长!我的任务是找到一种无需用户参与或运行 Access 即可以编程方式压缩和修复数据库的方法。经过一番搜索,我能够找到几个使用经典 ASP 和/或 VB6 完成此操作的示例。我采用了这些示例,将代码迁移到托管 C#,将其引入 ASP.NET 网站,并将该过程抽象为一个简单的实用函数。
背景
Microsoft 通过其 JET 框架提供了一种以编程方式压缩和修复数据库的方法。 JET 也是应用程序能够从 Microsoft Office 生态系统中的各种文件格式(包括 Access 和 Excel 文件)中读取和写入的方法。我们的应用程序使用 SQL Server Integration Services 通过 JET 提供程序将数据从 SQL Server 导出到 Access 数据库,然后用户通过 HTTP 下载该数据库。
Using the Code
该代码由一个位于 ASP.NET 网站的 App_Code 文件夹中的类中的 static
方法组成。该代码可以轻松地适应在桌面应用程序中运行 - 您只需要删除路径映射逻辑。
在编译此代码之前,需要执行一个关键步骤(别担心,这很简单)。向您的网站(或桌面应用程序)添加引用。在“添加引用”对话框中,转到 COM 选项卡。找到 Microsoft Jet 和复制对象库(DLL 文件是 msjro.dll),然后添加它。如果您正在使用网站,您会注意到 Visual Studio 将自动在您的 BIN 文件夹中创建几个互操作程序集。这些用于允许您的托管代码与涉及的 COM 对象进行通信。该过程是完全透明的 - 搜索 .NET COM Interop 以了解更多信息。
注意:以这种方式压缩数据库不一定可以并发执行。您需要根据需要实现并发和线程安全。
这是包含 XML 注释的代码(您也可以在上面下载它)
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
using JRO;
/// <summary>
/// Encapsulates small static utility functions.
/// </summary>
public class Utility
{
/// <summary>The connection to use to connect to
/// an Access database using JET.</summary>
public const string AccessOleDbConnectionStringFormat =
"Data Source={0};Provider=Microsoft.Jet.OLEDB.4.0;";
/// <summary>
/// Compacts an Access database using Microsoft JET COM
/// interop.
/// </summary>
/// <param name="fileName">
/// The filename of the Access database to compact. This
/// filename will be mapped to the appropriate path on the
/// web server, so use a tilde (~) to specify the web site
/// root folder. For example, "~/Downloads/Export.mdb".
/// The ASP.NET worker process must have been granted
/// permission to read and write this file, as well as to
/// create files in the folder in which this file resides.
/// In addition, Microsoft JET 4.0 or later must be
/// present on the server.
/// </param>
/// <returns>
/// True if the compact was successful. False can indicate
/// several possible problems including: unable to create
/// JET COM object, unable to find source file, unable to
/// create new compacted file, or unable to delete
/// original file.
/// </returns>
public static bool CompactJetDatabase(string fileName)
{
// I use this function as part of an AJAX page, so rather
// than throwing exceptions if errors are encountered, I
// simply return false and allow the page to handle the
// failure generically.
try
{
// Find the database on the web server
string oldFileName =
HttpContext.Current.Server.MapPath(fileName);
// JET will not compact the database in place, so we
// need to create a temporary filename to use
string newFileName =
Path.Combine(Path.GetDirectoryName(oldFileName),
Guid.NewGuid().ToString("N") + ".mdb");
// Obtain a reference to the JET engine
JetEngine engine =
(JetEngine)HttpContext.Current.Server.CreateObject(
"JRO.JetEngine");
// Compact the database (saves the compacted version to
// newFileName)
engine.CompactDatabase(
String.Format(
AccessOleDbConnectionStringFormat, oldFileName),
String.Format(
AccessOleDbConnectionStringFormat, newFileName));
// Delete the original database
File.Delete(oldFileName);
// Move (rename) the temporary compacted database to
// the original filename
File.Move(newFileName, oldFileName);
// The operation was successful
return true;
}
catch
{
// We encountered an error
return false;
}
}
}
贡献者
感谢 Roy Fine、Craig Starnes 和 Michael Brinkley 之前在其他语言中对这个问题的研究。
历史
- 2007 年 3 月 20 日 - 发布第一个版本