如何使用C#创建Access数据库并持续保存实时数据

Cha*_*arp 5 c# ms-access

我目前正在制作一个全天候运行的应用程序,并不断从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

必须有一个简单的解决方案,我不能是唯一使用Access而没有" Microsoft.Jet.OLEDB.4.0 "提供程序的解决方案.

(我还没有启动压缩文件的代码,如果你知道如何做到这一点,我很高兴听到它,但这里主要关注的是数据库问题.)

更新:问题可能不在于我最初的提供者,Microsoft.ACE.OLEDB.12.0允许我创建一个.accdb文件,但它只是一个空的txt文件,基本上有一个花哨的扩展,它无法打开或与MS Access一起使用.如何创建一个有效的.accdb文件?

Ren*_*uis 11

关于你的代码

说实话,我在你提交的代码示例中想要实现的目标不知所措.
从我所看到的,你只是创建一个文件RSLogixDB.accdb.
也许我错过了什么,但这根本不是你创建数据库的方式.

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

现在,还有一些解释.

Jet vs ACE

首先,ACCDB文件格式是Jet的完全改造的结果,现在称为ACE.它仅用于Access 2007/2010,并包含不向后兼容的新功能.

要打开此类文件,您必须安装Access 2007/2010(或至少是免费的Access Runtime)或Microsoft的特定ACE驱动程序.

关于32/64位

为了您的理智,无论您的OS位数如何,只使用Office和Access 32位.甚至微软也不建议使用64位版本,除非你将Excel推向极限.

  • 不能混合Office 32位和64位应用程序
  • 您无法在同一台计算机上安装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=;";
    
    Run Code Online (Sandbox Code Playgroud)
  • 在应用程序启动时打开与数据库的虚拟连接并保持打开直到您不需要数据库(例如压缩它或者当您的应用程序关闭时).
    这实际上是一项非常重要的性能改进:打开与Access数据库的新连接非常昂贵,因为驱动程序需要创建/销毁/更新.accdl锁定文件.
    如果保持与数据库的始终打开的连接,您将大大加快对它的读/写速度.有关此主题的更多信息,请查看此文章:
    OLE DB连接池在哪里?

回到任务

我会做你想要实现的方式:

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

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

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

  • 打开连接并从虚拟表中读取数据,但不要关闭它.保持开放.

  • 将数据整天保存到数据表中

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

  • 如果ADO.Net数据访问的标准性能不足以满足您的需求,请查看使用本机DAO例程.看看这个问题的答案:
    在.NET/C#中向Access写入大量记录(批量插入)

  • +1没有发布一些预先答案的人. (2认同)