首页 > 解决方案 > 如果 Ole.DB 提供程序在系统上可用,为什么 OleDbConnection.Open() 会抛出无法识别的数据库格式

问题描述

我在 Windows x64 上尝试了下一个代码,但代码被编译并作为 x86 运行。同样的行为是如果我在 Windows 7 或 10 x86 中运行应用程序。

static IList<string> GetOleDbProviders()
{
    OleDbEnumerator oleDbEnumerator = new OleDbEnumerator();
    DataTable oleDbProviders = oleDbEnumerator.GetElements();

    IDictionary<string, string> descriptions = new Dictionary<string, string>();
    int typeColumnIndex = oleDbProviders.Columns.IndexOf("SOURCES_TYPE");
    int nameColumnIndex = oleDbProviders.Columns.IndexOf("SOURCES_NAME");
    int descriptionColumnIndex = oleDbProviders.Columns.IndexOf("SOURCES_DESCRIPTION");

    foreach (DataRow dataRow in oleDbProviders.Rows)
    {
        int type = (int)dataRow[typeColumnIndex];

        if (type == 1)
        {
            string name = (string)dataRow[nameColumnIndex];
            string description = (string)dataRow[descriptionColumnIndex];
            descriptions.Add(name, description);
        }
    }

    IList<string> providers = new List<string>();

    foreach (KeyValuePair<string, string> pair in descriptions)
    {
        providers.Add(pair.Value);
    }

    return providers;
}

static void Test5()
{
    // has item 'Microsoft.Jet.Ole.DB.4.0'
    IList<string> providers = GetOleDbProviders();

    string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.\my.accdb";
    System.Data.Common.DbConnection connection = new OleDbConnection(connectionString);

    try
    {
        // throws OleDbException on 32 bit with message 'Unregonized database format'
        connection.Open();
    }
    catch (InvalidOperationException e)
    {
        // break point when running on 64-bit runtime
    }
    catch (OleDbException e)
    {
        // break point when running on 32-bit runtime
    }
}

如果 Jet.OleDb 是系统提供的,为什么 connection.Open() 会抛出异常?或者这是否意味着 Jet.OleDb 支持其他格式,但不支持 *.accdb。

当然,在安装Microsoft Access 2013 Runtime后它可以工作了,但仍然可以吗?如果不会从 oleDbEnumerator.GetElements() 返回 Microsoft.Jet.Ole.Db.4.0 提供程序并且会引发 ProviderNotFound 异常,这不是更正确吗?

在此处输入图像描述

编辑

安装Microsoft Access 2013 Runtime后仍然无法正常工作。您必须使用较新的ACE 提供程序而不是 Jet。必须相应地更新连接字符串。

标签: c#oledb

解决方案


或者这是否意味着 Jet.OleDb 支持其他格式,但不支持 *.accdb。

是 - 较旧版本的驱动程序将支持较旧的 mdb 格式。

根据文档

从 Access 2007 开始,.accdb 是默认的 Access 文件格式。

在 Access 2007 中引入 .accdb 文件格式之前,Access 文件格式使用 .mdb 文件扩展名。

如果您有兴趣,该链接将为您提供有关 mdb 和 accdb 之间差异的更多信息。

如果不会从 oleDbEnumerator.GetElements() 返回 Microsoft.Jet.Ole.Db.4.0 提供程序并且会引发 ProviderNotFound 异常,这不是更正确吗?

不,不会的。提供者那里。它不支持所有版本的 Access 数据库的事实并不意味着它不存在。如果它根本不可见,人们将无法使用驱动程序访问 mdb 文件——例如(破坏许多旧的 VB6 应用程序)。


推荐阅读