2

我有多个应用程序使用 MS Enterprise Library 和 Oracle ODP.Net 驱动程序连接到 Oracle。

一个应用程序,一个 Windows 服务,在尝试创建到 Oracle DB 的连接时抛出以下错误:

数据库“MyDBName”的连接字符串不存在或没有有效的提供程序。

另一个应用程序,一个 Web 服务,做同样的事情,而且运行良好。两者都在我的计算机上本地运行。

在 Windows 服务中,我检查了明显的情况:连接字符串实际上在那里,名称拼写正确,并且 Db 提供程序 Oracle.DataAccess.Client 在那里并且拼写正确。我还确认 ODP.net 已在 machine.config 中正确安装和配置(这必须是因为 Web 服务有效)。web 和 win 服务都使用 .net 4.5.1。所以我相信所有显而易见的事情都被排除了。

进入 ent lib 代码我发现异常的来源是因为这个方法在 windows 服务下调用时返回 false:

private static bool IsValidProviderName(string providerName)
{
    return DbProviderFactories.GetFactoryClasses().Rows.Find(providerName) != null;
}

在 Web 服务下运行时返回 true。在这两种情况下,提供的 providerName 的值都是相同的 (Oracle.DataAccess.Client)。然后我查看了 GetFactoryClasses() 返回的 Rows,发现在 windows 服务下,只有少数(大约一半)注册的工厂类从 machine.config 中返回,而 Oracle 不在其中。所以这就是它失败的原因。为了让它正常工作,我在 app.config 中为我的服务添加了以下内容:

<DbProviderFactories>
      <remove invariant="Oracle.ManagedDataAccess.Client"/>
      <remove invariant="Oracle.DataAccess.Client"/>

      <add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
      <add name="ODP.NET, Unmanaged Driver" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET, Unmanaged Driver" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

    </DbProviderFactories>

这些是直接从 machine.config 中复制出来的。

所以我的问题基本上是,为什么在相同版本的 .net 下运行的两个应用程序在枚举注册的 DbProviderFactories 时不会产生一致的结果?

4

0 回答 0