如何使用 C# 创建 Access 数据库并不断向其中保存实时数据

Posted

技术标签:

【中文标题】如何使用 C# 创建 Access 数据库并不断向其中保存实时数据【英文标题】:How to create an Access database using C# and continuously save real-time data to it 【发布时间】:2012-05-11 17:04:52 【问题描述】:

我目前正在制作一个 24/7 全天候运行并不断从 OPC 服务器收集信息的应用程序。

我现在需要做的是将此信息发送到数据库(.accdb-file)。这需要非常非常迅速地发生。我每毫秒从服务器获取一个新值,我需要以相同的速度将该值发送到数据库。最后,我每天 00:00 将数据库压缩为 .zip 文件。

我一直像疯子一样在网上搜索,但似乎找不到“最新”教程。到目前为止,我发现的每一个都使用“Microsoft.Jet.OLEDB.4.0”作为提供程序,但它在我的 Windows 7 PC 上不存在。

我制作了一个小应用程序来测试连接,我将在下面附上我当前的代码,以提示您到目前为止我所做的尝试,但这些似乎都不起作用。

private void button1_Click(object sender, EventArgs e)

    System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly();
    System.IO.Stream oStream = oAssembly.GetManifestResourceStream("RSLogixDB.accdb");
    System.IO.FileStream fileStream = new System.IO.FileStream("C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb", System.IO.FileMode.Create);

    byte[] abyt = new byte[oStream.Length];
    oStream.Read(abyt, 0, (int)oStream.Length);
    fileStream.Write(abyt, 0, (int)oStream.Length);
    fileStream.Close();
    if (fileStream != null)
    
        fileStream.Close();
        fileStream = null;
    
    if (oStream != null)
    
        oStream = null;
    

这是我尝试的第一种方法,这里我使用了一个自制的类,用于创建和写入文件。不幸的是,它不适用于 .accdb 文件。 (第一行的 cmets 包括我尝试过的提供程序。

private void button1_Click(object sender, EventArgs e)

    //sFileDia.ShowDialog();
    //Provider=Microsoft.ACE.OLEDB.12.0
    //Povider=.NET Framework Data Provider for OLE DB
    //Povider=Microsoft.Jet.OLEDB.4.0
    //Driver=Microsoft Access Driver (*.mdb, *.accdb);
    //Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;
    //Persist Security Info=False;
    //Provider=Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;Persist Security Info=False
    string RSLogixDB = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;Persist Security Info=False";
    string RSLogixDBPath = "C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb";
    OleDbConnection connection = new OleDbConnection(RSLogixDB);
    string connectionStr = connection.ConnectionString;

    //OleDbDataReader dataReader = new OleDbDataReader(RSLogixDB);
    ImportExport textwriter = new ImportExport();
    textwriter.setExportPath(RSLogixDBPath);
    textwriter.endExport();

必须有一个简单的解决方案,如果没有“Microsoft.Jet.OLEDB.4.0”提供程序,我不能成为唯一使用 Access 的人。

(我还没有开始压缩文件的代码,如果你知道如何做我很高兴听到它,但这里的主要焦点是数据库问题。)

更新:问题可能并不像我最初那样出在提供商身上,Microsoft.ACE.OLEDB.12.0 允许我创建一个 .accdb 文件,但它只是一个带有花哨扩展名的空 txt 文件基本上,它不能用 MS Access 打开或使用。如何制作有效的 .accdb 文件?

【问题讨论】:

JET 4.0 存在于 Windows 7 上,但仅适用于 x86。您需要使用 ACE 连接到 accdb。如果您的 C# 应用程序是 AnyCPU 并且您在 64 位平台上,那么您需要使用 64 位版本(Access 2010 x64 数据库引擎) @ta.speot.is "Microsoft.ACE.OLEDB.12.0" 那么应该作为提供者工作吗? 如果您使用的是 x64,那么可以,但您需要安装 Access 2010 x64 数据库引擎。 @ta.speot.is 我使用的是 2007 版的 MS Access。我还使用 2010 db 引擎吗? 如果您使用的是 x86,则可以使用 2007 版本。如果您使用的是 x64,则需要 Access 2010 x64。 【参考方案1】:

关于您的代码

老实说,我不知道您在提供的代码示例中试图实现什么。 据我所知,您只是在创建一个文件RSLogixDB.accdb。 也许我遗漏了一些东西,但这根本不是您创建数据库的方式。

您是否查看并尝试过这些 SO 问题的答案中的代码:

How i Create Access Database at runtime in C#? How to create Microsoft Access database in C# programmatically?

现在,还有一些解释。

Jet vs ACE

首先,ACCDB 文件格式是对现在称为 ACE 的 Jet 进行全面改造的结果。 它仅与 Access 2007/2010 一起使用,并且包含不向后兼容的新功能。

要打开此类文件,您必须安装 Access 2007/2010(或至少免费的Access Runtime)或特定的ACE drivers from Microsoft。

关于 32/64 位

为了您的理智,无论您的操作系统位数如何,都只能使用 Office 和 Access 32 位。即使是Microsoft doesn't recommend using the 64 bits version,除非您将 Excel 推向极限。

你不能mix Office 32 bits and 64 bits applications 您不能在同一台机器上安装 32 位和 64 位 ACE 驱动程序 使用 ACE 驱动程序的 2007 或 2010 版本,但避免同时安装这两种驱动程序。 确保您的 .Net 应用程序编译为与安装的 Access/ACE 驱动程序相同的位数(因此,如果您遵循上述建议,则应专门编译为 x86,不是 AnyCPU!)。

性能

如果您遵守一些规则,您可以使用 Access 数据库获得非常不错的性能:

如果可能,将数据库与将写入它的应用程序保持在同一台机器上(避免网络速度变慢)

如果您的应用程序是唯一使用数据库的应用程序,请以独占模式而不是共享模式打开数据库:

// Share Mode=16 - use if multiple users must have simultaneous access to the db
string constr = @"Provider=Microsoft.ACE.OLEDB.12.0;Mode=16;Data Source=C:\...\RSLogixDB.accdb;user id=;password=;";

// Share Mode=12 - exclusive mode if only your app needs access to the db
string constr = @"Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source=C:\...\RSLogixDB.accdb;user id=;password=;";

在您的应用程序启动时打开一个到数据库的虚拟连接并保持打开状态,直到您不需要数据库(例如压缩它或当您的应用程序关闭时)。 这实际上是一个非常重要的性能改进:打开到 Access 数据库的新连接代价高昂,因为驱动程序需要创建/销毁/更新.accdl 锁定文件。 如果您保持与数据库的始终打开的连接,您将大大加快对它的读/写。有关此主题的更多信息,请查看这篇文章:Where is the OLE DB connection pooling?

回到任务

我会做你想要达到的目标的方式:

使用 Access 手动创建一个简单的数据库 RSLogixDB.accdb,其中包含将保存数据的表。 还要在其中创建一个dummy 表,其中包含很少或没有数据。我们将使用它来保持连接打开并避免锁定文件性能问题。

如果您需要每天从头开始重新创建数据库,则保留该原始数据库的副本作为模板,然后复制该模板并用新的每日数据填充副本。

如果您是数据库的唯一用户,请以独占模式打开它。

打开一个连接并从虚拟表中读取数据,但不要关闭它。保持打开状态。

全天将数据保存到您的数据表中

午夜,关闭数据库(关闭虚拟表),确保锁定文件.accdl 已消失,然后压缩数据库。 如果需要从空数据库开始,请用模板替换数据库。 我还会在压缩之前压缩数据库以减小其大小。

如果 ADO.Net 数据访问的标准性能不足以满足您的情况,请查看使用本机 DAO 例程。查看这个 SO 问题的答案:Writing large number of records (bulk insert) to Access in .NET/C#

【讨论】:

我只想补充一点,Windows 不是real-time operating system。由于 OP 试图在某种过程控制应用程序中使用 Windows 下的 Access 数据库,这可能是一个非常大的问题。可能不会。 虽然不支持/不推荐,但实际上可以(至少有时)在同一台机器上安装 32 位和 64 位 ACE 驱动程序:从管理员命令提示符进行安装并使用/passive/quiet 开关中的一个或其他(取决于版本)强制完成安装。我没有发现在同一台机器上安装的两组驱动程序有任何问题。【参考方案2】:

如果您需要连接字符串来连接到特定数据库,那么第一站应该始终是http://www.connectionstrings.com/

对于 Access,您可能会发现此页面很有帮助:http://www.connectionstrings.com/access-2007

【讨论】:

是的,这就是我在第二个代码示例中使用的那个。 string RSLogixDB = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;Persist Security Info=False"; 确实是一个非常有用的网站。【参考方案3】:

我为你找到了这个。 Connecting to MS Access (Windows 7)

这个forum thread 也会帮助你。

谢谢

保罗。

【讨论】:

虽然理论上可以回答这个问题,但我们希望您在回答中包含链接文章的基本部分,并提供link for reference。如果不这样做,答案就会面临链接失效的风险。【参考方案4】:

我认为您的连接无法建立,因为 Jet OLEDB 驱动程序未随 Windows 7 提供,但需要单独安装。一种方法是安装 Microsoft Access,另一种方法是从 Microsoft 查找 MDAC 可再发行包(MDAC = Microsoft 数据访问组件)。

您可以按照以下链接上的说明检查您是否拥有哪个版本的 MDAC:

http://support.microsoft.com/kb/301202/en-us

【讨论】:

JET 随 Windows 7 一起提供,它是 WDAC 的一部分。不过,Windows 不附带 64 位版本,因为没有 64 位版本的 JET。

以上是关于如何使用 C# 创建 Access 数据库并不断向其中保存实时数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 和 OleDB 向 Access 数据库表中添加富文本列?

C#如何创建一张access 表格

如何在 C# 编程中使用 access 数据库修复和创建日志

如何在 C# 中创建 Microsoft Access 数据库? [复制]

C# 向Access数据库插入数据时提示INSERT INTO语法错误

在C# winform中使用 richtextbox 向access保存及读取 图文混排数据(有源码,帮忙改一下)