[英]Why OleDbConnection.Open() throws Unrecognized database format if Ole.DB provider is available on the system
I tried next code on Windows x64, but the code is compiled and run as x86. 我在Windows x64上尝试了下一代码,但代码编译后运行为x86。 The same behaviour is if I run the application in Windows 7 or 10 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
}
}
Why would connection.Open() throw an exception if the Jet.OleDb is provided by the system? 如果系统提供Jet.OleDb,为什么connection.Open()会抛出异常? Or does this mean that Jet.OleDb has support for other formats but not *.accdb. 或者这是否意味着Jet.OleDb支持其他格式,但不支持* .accdb。
Of course after installing Microsoft Access 2013 Runtime it works, but still? 当然,在安装Microsoft Access 2013 Runtime之后它仍然有效,但仍然如此? Wouldn't be more correct if Microsoft.Jet.Ole.Db.4.0 provider won't be returned from oleDbEnumerator.GetElements() and ProviderNotFound exception would be thrown? 如果不从oleDbEnumerator.GetElements()返回Microsoft.Jet.Ole.Db.4.0提供程序并且抛出ProviderNotFound异常,那么会更正确吗?
EDIT 编辑
After installing Microsoft Access 2013 Runtime it still does not work . 安装Microsoft Access 2013 Runtime后,它仍然无法正常工作 。 You have to use newer ACE provider instead of Jet. 您必须使用较新的ACE提供程序而不是Jet。 Connection string must be updated accordingly. 必须相应地更新连接字符串。
Or does this mean that Jet.OleDb has support for other formats but not *.accdb. 或者这是否意味着Jet.OleDb支持其他格式,但不支持* .accdb。
Yes - the older versions of the driver will support the older mdb format. 是的 - 旧版本的驱动程序将支持旧的mdb格式。
Starting with Access 2007, .accdb is the default Access file format. 从Access 2007开始,.accdb是默认的Access文件格式。
Before the .accdb file format was introduced in Access 2007, Access file formats used the .mdb file extension. 在Access 2007中引入.accdb文件格式之前,Access文件格式使用.mdb文件扩展名。
That link will give you more information about the differences between mdb and accdb if you are interested. 如果您感兴趣,该链接将为您提供有关mdb和accdb之间差异的更多信息。
Wouldn't be more correct if Microsoft.Jet.Ole.Db.4.0 provider won't be returned from oleDbEnumerator.GetElements() and ProviderNotFound exception would be thrown? 如果不从oleDbEnumerator.GetElements()返回Microsoft.Jet.Ole.Db.4.0提供程序并且抛出ProviderNotFound异常,那么会更正确吗?
No, it wouldn't be. 不,它不会。 The provider is there. 提供者在那里。 The fact it doesn't support all versions of Access databases doesn't mean it doesn't exist . 它不支持所有版本的Access数据库并不意味着它不存在 。 If it wasn't visible at all, people wouldn't be able to use the driver to access mdb files - as an example (breaking lots of old VB6 apps). 如果它根本不可见,人们将无法使用驱动程序访问mdb文件 - 作为一个例子(破坏了许多旧的VB6应用程序)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.