为什么设置 OLEDBConnection.Connection 会抛出异常 (HRESULT: 0x800A03EC)?

Why setting OLEDBConnection.Connection throws Exception (HRESULT: 0x800A03EC)?

我正在使用 Excel Interop 命名空间来修改 Excel 工作簿连接中的连接字符串。

为什么当我尝试设置连接时 属性 (MSDN OLEDBConnection.Connection) 在赋值行上抛出错误?

Exception from HRESULT: 0x800A03EC

application = new Application();
Workbook wb = application.Workbooks.Open(file.FullName);
Sheets wbs = wb.Worksheets;
IEnumerable<Workbook> workbooks = application.Workbooks.Cast<Workbook>();

foreach (var connection in wb.Connections.Cast<WorkbookConnection>()
    .Where(c => c.Type == XlConnectionType.xlConnectionTypeOLEDB))
{
    connection.OLEDBConnection.Connection = "Test Connection String";
}

application.Quit();

但是,如下所示调用 Replace 方法是有效的。我发现这是解决方法,不确定为什么 Replace 在这种情况下有效。

application = new Application();
Workbook wb = application.Workbooks.Open(file.FullName);
Sheets wbs = wb.Worksheets;
IEnumerable<Workbook> workbooks = application.Workbooks.Cast<Workbook>();

foreach (var connection in wb.Connections.Cast<WorkbookConnection>()
    .Where(c => c.Type == XlConnectionType.xlConnectionTypeOLEDB))
{
    var conString = connection.OLEDBConnection.Connection.ToString();
    connection.OLEDBConnection.Connection = 
        conString.Replace("Test Connection String", "New Test Connection String");
}

application.Quit();

这实际上是我可以更改连接字符串的唯一方法,因此询问 set 可能引发错误的原因是什么。

可能有很多原因。所有的共同点是向后兼容。 例如正在打开 XLS 文件。

同时规范化完整文件路径 - 使用反斜杠。将 DefaultSaveFormat 设置为 xlOpenXML 或 'application' 上的类似内容,如果您确定您不是在使用旧版本 Excel 创建的文件上操作。

您指定的代码的 COM 错误通常在它无法解析对象名称(在工作簿中)或在解析此类名称时遇到任何其他问题时抛出。

如果这些都失败了,检查这个 link:

http://www.hagrin.com/319/exception-hresult-0x800a03ec-excel-net-sql-and-windows-server-2008

我找到了一种使用 OpenXML 的方法,似乎通过互操作更改连接字符串并不是唯一的方法。

using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(file.FullName, true))
{
    WorkbookPart workbookpart = excelDoc.WorkbookPart;
    ConnectionsPart connPart = workbookpart.ConnectionsPart;

    string spreadsheetmlNamespace = @"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
    NameTable nt = new NameTable();
    XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
    nsManager.AddNamespace("sh", spreadsheetmlNamespace);

    XmlDocument xdoc = new XmlDocument(nt);
    xdoc.Load(connPart.GetStream());

    XmlNode oxmlNode = xdoc.SelectSingleNode("/sh:connections/sh:connection/sh:dbPr/@connection", nsManager);
    string newConnection = ReplaceInitialCatalog(oxmlNode.Value, repConfig.DbName);
    oxmlNode.Value = oxmlNode.Value.Replace(oxmlNode.Value, newConnection);

    //Truncates part with FeedData
    connPart.FeedData(connPart.GetStream());
    xdoc.Save(connPart.GetStream());
}

问题是连接字符串似乎有特殊的前缀(OLEDB;),它在分配时被检查,所以可以通过这个解决:

...
connection.OLEDBConnection.Connection = "OLEDB;Test Connection String";
...

前缀在连接字符串检索时显示出来,因此是线索。

尽管由于易于测试而推荐 OpenXML。