我的任务是将遗留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()
的调用成功。
如果我尝试在C#端设置ActiveConnection
,就像这样:
var catalog = new ADOX.Catalog();
catalog.ActiveConnection = conn;
一切正常。
现在,我可以通过简单地在C#端实例化ADOX并将其传递给VB6来解决这个问题,但调整VB6代码(当然没有单个单元测试)可以证明是PITA,而我我甚至不确定首先要做的很容易(因为应用程序可以同时使用多个Access DB,根据需要打开和关闭每个Access的连接)。
所以,任何人都知道我做错了什么?从C#开始,我尝试从.NET选项卡和COM选项卡中引用ADODB(我从COM选项卡中选择的ADO版本是正确的:2.5 ......再次,不要问),但仍然没有喜悦。
修改
当我尝试将RecordSet的ActiveConnection属性分配给来自C#的连接时,会发生完全相同的事情,如下所示:
Dim rs As New ADODB.Recordset
Set rs.ActiveConnection = theAdoConnectionComingFromDotNet
我能想到的另一种解决方法,因为ActiveConnection是一个Variant,它将把它设置为连接的ConnectionString属性。这是有效的,但它每次都会创建并打开一个新的连接,坦白说我不喜欢它。
答案 0 :(得分:1)
这似乎是错误的方式,但这与我遇到的问题非常相似 - 其中ADO停止在Win7机器上重新编译然后在XP机器上使用的COM对象中工作 - 我认为这可能归结为同一件事情。即,broke MDAC ADO in COM objects(非常长的线程,期望缓慢加载)的灾难性Windows更新。如果是这样,官方修正可以是found here。
如果不是这样且您找不到解决方案,我认为您最好的做法是使用您在编辑中提到的连接字符串解决方法。这不是理想的,但你说你将开始重写DLL,所以它只是一个临时的安排。