MSTest.exe 无法加载 ADO.NET 数据提供程序?
我在使用 MSTest 时遇到了一个非常奇怪的问题。我有一个测试更像是集成测试,并且需要连接到数据库。它通过调用以下内容来获取 ADO.NET 数据提供程序工厂来实现此目的:
var factory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
在我的 app.config 文件中,我有:
<system.data>
<DbProviderFactories>
<add name="Oracle Data Provider" invariant="Oracle.DataAccess.Client" description=".Net Framework Data Provider for Oracle" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
这个工作得很好,并且如果我在 Visual Studio 中运行它,测试就会通过。但是,如果我打开命令提示符,并使用 MSTest.exe /testcontainer:...
运行它,那么我的测试就会失败,但有一个例外:
System.Configuration.ConfigurationErrorsException
Message: Failed to find or load the registered .Net Framework Data Provider.
奇怪的是,如果我查询 DBProviderFacotry 类,我确实看到了我的“Oracle.DataAccess.Client”提供程序,但尝试实际获取它的实例会引发异常:
var name = DbProviderFactories.GetFactoryClasses().Rows[1]["InvariantName"]; // returns "Oracle.DataAccess.Client"
var fact = DbProviderFactories.GetFactory("Oracle.DataAccess.Client"); // throws exception
同样,这仅在从 MSTest.exe 命令行运行时失败,并且可以工作在 VisualStudio 2008 中很好。有人有什么想法吗?
更新:
我发现了另一个有趣的细节...在我的app.config中,我实际上在添加我的oracle条目之前清除了提供者集合,因为如果它已经存在于machine.config中,那么它会导致错误:
<system.data>
<DbProviderFactories>
<clear />
<add name="Oracle Data Provider" invariant="Oracle.DataAccess.Client" description=".Net Framework Data Provider for Oracle" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
现在,我刚刚发现,如果我从 app.config 中完全删除它,并且根本不指定 DbProviderFactories,那么它就可以正常工作!
奇怪...
更新 2
好吧,我想我已经弄清楚了。在我的 app.config 中,如果我指定程序集的完整/强名称,那么它在 VisualStudio 和命令行中都可以工作:
<add name="Oracle Data Provider"
invariant="Oracle.DataAccess.Client"
description="Oracle Data Provider for .NET"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
但短名称仅在 VisualStudio 中工作,不能在命令行上工作:
<add name="Oracle Data Provider"
invariant="Oracle.DataAccess.Client"
description=".Net Framework Data Provider for Oracle"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
现在我只是希望我明白为什么......:)
I'm having a really strange issue with MSTest. I have a test that is more of an integration test, and needs to connect to the database. It does this by getting the ADO.NET data provider factory through a call to:
var factory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
In my app.config file, I have:
<system.data>
<DbProviderFactories>
<add name="Oracle Data Provider" invariant="Oracle.DataAccess.Client" description=".Net Framework Data Provider for Oracle" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
This works perfectly fine and the test passes if I run it in Visual Studio. However, if I open a command prompt, and run it using MSTest.exe /testcontainer:...
Then my test fails, with the exception:
System.Configuration.ConfigurationErrorsException
Message: Failed to find or load the registered .Net Framework Data Provider.
The odd thing is that if I query the DBProviderFacotry classes, I do see my "Oracle.DataAccess.Client" provider, but trying to actually get an instance of it throws an exception:
var name = DbProviderFactories.GetFactoryClasses().Rows[1]["InvariantName"]; // returns "Oracle.DataAccess.Client"
var fact = DbProviderFactories.GetFactory("Oracle.DataAccess.Client"); // throws exception
Again, this only fails when run from the MSTest.exe command line, and works fine in VisualStudio 2008. Anyone have any ideas?
Update:
I found out another interesting detail... In my app.config, I actually do a clear of the provider collection before adding my oracle entry, because if it already existed in machine.config, it would cause errors:
<system.data>
<DbProviderFactories>
<clear />
<add name="Oracle Data Provider" invariant="Oracle.DataAccess.Client" description=".Net Framework Data Provider for Oracle" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
Now, what I just found is that if I completely remove this from the app.config, and don't specify the DbProviderFactories at all, then it works fine!
Strange...
Update 2
OK, I guess I sort of figured this out. In my app.config, if I specify the full/strong name for the assembly, then it works, in both VisualStudio, and from the command line:
<add name="Oracle Data Provider"
invariant="Oracle.DataAccess.Client"
description="Oracle Data Provider for .NET"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342" />
But the short name only works in VisualStudio, not on the command line:
<add name="Oracle Data Provider"
invariant="Oracle.DataAccess.Client"
description=".Net Framework Data Provider for Oracle"
type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" />
Now I just wish I understood why... :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这里回答我自己的问题,但我终于弄清楚了:
当 VisualStudio 构建它时,我的 Oracle.DataAccess.dll 确实最终出现在我的 \bin\Debug 文件夹中。但是,当 MSTest.exe 运行时,它不会将该 .dll 复制到实际运行测试的新文件夹中。由于某种原因,它复制了其他 30 多个文件,但不复制那个文件?
无论如何,这就是为什么添加完整的程序集名称有效的原因;因为这样它就可以从 GAC 而不是本地文件夹加载它。
Answering my own question here, but I finally figured this out:
My Oracle.DataAccess.dll does end up in my \bin\Debug folder when VisualStudio builds it. However, when MSTest.exe runs, it does not copy that .dll to the new folder where the test is actually run. For some reason it copies the other 30-some files, but not that one?
Anyway, thats why adding the full assembly name worked; because then it could load it from the GAC instead of the local folder.
我可以使用以下代码解决该问题:
I could fix the issue using the following code: