4

我的任务是将遗留的 VB6 应用程序(使用 MS Access 作为数据库,不要问)增量移植到 .NET。

这将是一个很长的文章,但我认为最好提供一些背景信息。

此应用程序有一个带有菜单的主 MDI 表单,该菜单是根据应用程序文件夹中的 DLL 动态创建的。它本质上是一种插件:每个 DLL 都由一个菜单项表示,当单击该菜单项时,将打开 DLL 中包含的主窗体,并SetParent()根据需要进行调用。

MDI 表格是我的起点。我想重写足够多的内容(当然,我要进行重新设计和单元测试)以便能够打开所述表单。一旦我确定了那个,我将开始一次重写一个 DLL。

每个 DLL 都需要一个 ADO 连接,我已经能够从 C# 传递它。

问题是,其中一个插件(至少,但可能还有许多其他插件)使用 ADOX 在数据库上做事,问题就在这里:当我尝试将 ADOX.Catalog 的 ActiveConnection 属性设置为 ADO 连接时,所有我得到的是运行时错误 3001:Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.

我一生都无法弄清楚我做错了什么。

VB6 代码尽可能简单:

Dim c As New ADOX.Catalog
Set c.ActiveConnection = theAdoConnectionComingFromDotNet   ' error!

创建 ADO 连接的 C# 代码与 VB 代码一样简单:

var conn = new ADODB.Connection();
conn.Open("Provider=Microsoft.JET.Oledb;[...]");

并且调用Open()成功。如果我尝试ActiveConnection在 C# 端设置 ,如下所示:

var catalog = new ADOX.Catalog();
catalog.ActiveConnection = conn;

一切正常。

现在,我可以通过简单地在 C# 端实例化 ADOX 并将其传递给 VB6 来解决这个问题,但是调整 VB6 代码(当然没有单个单元测试)可以证明是一个 PITA,我不是甚至确保一开始这很容易(因为该应用程序可以一次使用多个 Access DB,并根据需要打开和关闭与每个数据库的连接)。

那么,有人知道我做错了什么吗?在 C# 中,我尝试从 .NET 选项卡和 COM 选项卡中引用 ADODB(我从 COM 选项卡中选择的 ADO 版本是正确的:2.5...再次,不要问),但仍然没有喜悦。

编辑

当我尝试将 RecordSet 的 ActiveConnection 属性分配给来自 C# 的连接时,会发生完全相同的事情,如下所示:

Dim rs As New ADODB.Recordset
Set rs.ActiveConnection = theAdoConnectionComingFromDotNet

由于 ActiveConnection 是一个变体,我能想到的另一个解决方法是将其设置为连接的 ConnectionString 属性。这行得通,但它每次都会创建并打开一个新连接,坦率地说我不喜欢它。

4

1 回答 1

1

这似乎是错误的方式,但这与我遇到的问题非常相似——ADO 停止在一个 COM 对象中工作,该对象在 Win7 机器上重新编译然后在 XP 机器上使用——我认为这可能是同一件事. 即,破坏 COM 对象中的 MDAC ADO的灾难性 Windows 更新(非常长的线程,预计加载缓慢)。如果是这样,可以在这里找到官方修复。

如果不是这样并且您找不到解决方案,我认为您最好的做法是仅使用您在编辑中提到的连接字符串解决方法。这并不理想,但您说无论如何您都将开始重写 DLL,因此这只是临时安排。

于 2012-05-15T18:11:23.607 回答