我们在打开从 OleDbConnectionStringBuilder.ConnectionString
属性的返回值创建的OleDbConnection
时遇到了意外的异常。正在使用OleDbConnectionStringBuilder
将任何相对DataSource
路径更新为绝对路径。
当我们调用OleDbConnection.Open
时,我们会收到一个System.Data.OleDb.OleDbException
异常,并且消息指出:
"初始化字符串的格式不符合 OLE DB 规范。
代码为:
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;
的连接字符串之前,我们对此没有任何问题。属性返回的值OleDbConnectionStringBuilder.ConnectionString
返回带有引号值的属性。例如:
(变量"连接字符串"):
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:SomePathSome Database.mdb";Persist Security Info=False;Mode="ReadWrite|Share Deny None"
不带引号的Mode
值可以正常工作!
我有几个问题:
- 这是设计使然吗?为什么它返回不兼容的值?
- 如何在不重复
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);
如果您负责原始连接字符串,另一种选择是在将"共享拒绝无"中的空格替换为占位符,例如"共享###Deny###None",然后再将其提交到 oleDBbuilder。最后,在使用 oleDBbuilder.ConnectionString 之前,必须再次撤消此替换。
要回答你的第一个问题("这是设计使然吗?"),我只能推测。对我来说,它看起来更像是粗心的编程。网络程序员忽略了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"