禁用/刷新OleDbConnection缓存

时间:2012-06-28 10:45:20

标签: c# caching oledb jet oledbconnection

我一直在与OleDbConnection战斗一段时间,现在试图让它不缓存。基本上我正在访问一个共享的Access数据库,该数据库是从另一个应用程序写入的,然后我正在读回值(检查它是否通过Last Write时间和随后的1秒延迟刷新)。

不幸的是,这完全不可靠。

我一直在阅读(并且疯狂)如何禁用连接池,随后在每次可能的更新后,在重新连接之前执行以下操作:

_connection.Close();
_connection.Dispose();
_connection = null;
OleDbConnection.ReleaseObjectPool();
GC.Collect();

除此之外,连接字符串还会禁用与OLE DB Services = -2的连接池。最后,我还在Jet 4.0的注册表中将PageTimeout更改为“10”。

遗憾的是,所有这些措施都没有效果。现在我唯一想到的就是this Microsoft KB Article中提到的内容,并调用JRO.JetEngine.RefreshCache。唯一的问题是它的论点是ADODB.Connection。我宁愿不重写我的整个数据库层以及我的软件正在读取记录以使用传统COM对象来获得此功能,但似乎它可能是唯一的方法。

我的问题是,虽然目前正在进行重写以使用ADODB(甚至不是ADO.NET!)的任务,是否可以禁用OleDbConnection的缓存?

3 个答案:

答案 0 :(得分:0)

你可能有一些运气设置&#34 ;; Jet OLEDB:Flush Transaction Timeout"属性为0或一些低数字。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms681754(v=vs.85).aspx

答案 1 :(得分:0)

最后,我找到了一种解决方法:使用OdbcConnection而不是OleDbConnection。

这是旧代码:

string mdbConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + mdbFile + ";OLE DB Services=-2";
using (OleDbConnection conn = new OleDbConnection(mdbConnectionString)) {
    conn.Open();
    //Do your query
}

这是新的:

string mdbConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" + mdbFile;
using (OdbcConnection conn = new OdbcConnection(mdbConnectionString)) {
    conn.Open();
    //Do your query
}

一切正常。

答案 2 :(得分:0)

32位应用程序

多年来,我一直在32位C#应用程序中执行此操作以刷新缓存:

public static void RefreshDatabaseCache(
    string connectionString)
{
    // The type of the ADODB connection. Used for dynamically creating.
    var adodbType = Type.GetTypeFromProgID(@"ADODB.Connection");

    // The main ADODB connection object.
    var adodbInstance = Activator.CreateInstance(adodbType);

    // --

    // Open the connection.
    adodbType.InvokeMember(
        @"Open",
        BindingFlags.InvokeMethod,
        null,
        adodbInstance,
        new object[]
        {
            connectionString,
            string.Empty,
            string.Empty,
            0
        });

    try
    {
        // The type of the JET engine. Used for dynamically creating.
        var jroType = Type.GetTypeFromProgID(@"JRO.JetEngine");

        // The main JET engine object.
        var jroInstance = Activator.CreateInstance(jroType);

        // Refresh the cache.
        jroType.InvokeMember(
            @"RefreshCache",
            BindingFlags.InvokeMethod,
            null,
            jroInstance,
            new[]
            {
                adodbInstance
            });
    }
    finally
    {
        // Close the connection.
        adodbType.InvokeMember(
            @"Close",
            BindingFlags.InvokeMethod,
            null,
            adodbInstance,
            new object[]
            {
            });
    }
}

我在整个应用程序中使用OleDB,就在上面的函数中,我使用的是“ ADODB”。

64位应用程序

目前,在64位C#应用程序中,我确实知道的实现方式。