OleDbConnectionStringBuilder 返回值与 OleDbConnection 不兼容
OleDbConnectionStringBuilder returning value incompatible with OleDbConnection
我们 运行 在打开从 OleDbConnectionStringBuilder.ConnectionString
属性 的 return 值创建的 OleDbConnection
时抛出意外异常。正在使用 OleDbConnectionStringBuilder
将任何相对 DataSource
路径更新为绝对路径。
当我们调用 OleDbConnection.Open
时出现 System.Data.OleDb.OleDbException
异常并且消息状态为:
"Format of the initialization string does not conform to the OLE DB specification.".
密码是:
var oleDBbuilder = new OleDbConnectionStringBuilder(connectString);
oleDBbuilder.DataSource = ResolveDataSourcePath(oleDBbuilder.DataSource);
m_pOleDb = new OleDbConnection(oleDBbuilder.ConnectionString);
m_pOleDb.Open(); // <-- Throws exception here
在我们尝试处理包含值 Mode=ReadWrite|Share Deny None;
的连接字符串之前,我们对此没有任何问题。值 return 由 OleDbConnectionStringBuilder.ConnectionString
属性 return 编辑 属性 并引用其值。例如:
此连接字符串(变量'connectString'):
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\SomePath\@Some Database.mdb;Mode=ReadWrite|Share Deny None;Persist Security Info=False
变成 (OleDbConnectionStringBuilder.ConnectionString):
Provider=Microsoft.Jet.OLEDB.4.0;Data Source="c:\SomePath\Some Database.mdb";Persist Security Info=False;Mode="ReadWrite|Share Deny None"
不带引号的 Mode
值可以正常工作!
我有几个问题:
- 这是设计使然吗?为什么它 return 是一个不兼容的值?
- 如何在不重复
OleDbConnectionStringBuilder
的工作的情况下解决这个问题?
我没有真正的答案,只是变通。
在使用 oleDBbuilder.ConnectionString 之前,您可以使用如下正则表达式删除引号:
m_pOleDb = new OleDbConnection(Regex.Replace(oleDBbuilder.ConnectionString, @"(?<=mode=)((?<quote>""|')?(?<inner>[^;]+?)\k<quote>)", "${inner}", RegexOptions.IgnoreCase));
而不是
m_pOleDb = new OleDbConnection(oleDBbuilder.ConnectionString);
如果您负责原始连接字符串,另一种选择是将“Share Deny None”中的空格替换为“Share###Deny###[=38”等占位符=]”,然后将其提交给 oleDBbuilder。最后,在使用 oleDBbuilder.ConnectionString 之前,必须再次撤消此替换。
要回答您的第一个问题(“这是设计使然吗?”),我只能推测。对我来说,它看起来更像是粗心的编程。 Net 程序员忽略了 ADODB.ConnectionModeEnum 有一种 flags 属性,所以可以用 Or.
添加多个值。
编辑
首先:对我来说,引号中包含空格的键似乎是一种误解。这仅对于带有前导或尾随空格的键是必需的。
其次:我做了一些测试。这适用于 Provider=VFPOLEDB.1 和 Provider=Microsoft.ACE.OLEDB.12.0:
Mode=ReadWrite|Share Deny None
Mode=ReadWrite|"Share Deny None"
这不起作用:
Mode="ReadWrite|Share Deny None"
Mode="ReadWrite"|"Share Deny None"
我们 运行 在打开从 OleDbConnectionStringBuilder.ConnectionString
属性 的 return 值创建的 OleDbConnection
时抛出意外异常。正在使用 OleDbConnectionStringBuilder
将任何相对 DataSource
路径更新为绝对路径。
当我们调用 OleDbConnection.Open
时出现 System.Data.OleDb.OleDbException
异常并且消息状态为:
"Format of the initialization string does not conform to the OLE DB specification.".
密码是:
var oleDBbuilder = new OleDbConnectionStringBuilder(connectString);
oleDBbuilder.DataSource = ResolveDataSourcePath(oleDBbuilder.DataSource);
m_pOleDb = new OleDbConnection(oleDBbuilder.ConnectionString);
m_pOleDb.Open(); // <-- Throws exception here
在我们尝试处理包含值 Mode=ReadWrite|Share Deny None;
的连接字符串之前,我们对此没有任何问题。值 return 由 OleDbConnectionStringBuilder.ConnectionString
属性 return 编辑 属性 并引用其值。例如:
此连接字符串(变量'connectString'):
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\SomePath\@Some Database.mdb;Mode=ReadWrite|Share Deny None;Persist Security Info=False
变成 (OleDbConnectionStringBuilder.ConnectionString):
Provider=Microsoft.Jet.OLEDB.4.0;Data Source="c:\SomePath\Some Database.mdb";Persist Security Info=False;Mode="ReadWrite|Share Deny None"
不带引号的 Mode
值可以正常工作!
我有几个问题:
- 这是设计使然吗?为什么它 return 是一个不兼容的值?
- 如何在不重复
OleDbConnectionStringBuilder
的工作的情况下解决这个问题?
我没有真正的答案,只是变通。
在使用 oleDBbuilder.ConnectionString 之前,您可以使用如下正则表达式删除引号:
m_pOleDb = new OleDbConnection(Regex.Replace(oleDBbuilder.ConnectionString, @"(?<=mode=)((?<quote>""|')?(?<inner>[^;]+?)\k<quote>)", "${inner}", RegexOptions.IgnoreCase));
而不是
m_pOleDb = new OleDbConnection(oleDBbuilder.ConnectionString);
如果您负责原始连接字符串,另一种选择是将“Share Deny None”中的空格替换为“Share###Deny###[=38”等占位符=]”,然后将其提交给 oleDBbuilder。最后,在使用 oleDBbuilder.ConnectionString 之前,必须再次撤消此替换。
要回答您的第一个问题(“这是设计使然吗?”),我只能推测。对我来说,它看起来更像是粗心的编程。 Net 程序员忽略了 ADODB.ConnectionModeEnum 有一种 flags 属性,所以可以用 Or.
添加多个值。编辑
首先:对我来说,引号中包含空格的键似乎是一种误解。这仅对于带有前导或尾随空格的键是必需的。
其次:我做了一些测试。这适用于 Provider=VFPOLEDB.1 和 Provider=Microsoft.ACE.OLEDB.12.0:
Mode=ReadWrite|Share Deny None
Mode=ReadWrite|"Share Deny None"
这不起作用:
Mode="ReadWrite|Share Deny None"
Mode="ReadWrite"|"Share Deny None"