尝试从使用最少设置配置的 C# 程序连接到 Oracle 10g 数据库时出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8603883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 00:31:17  来源:igfitidea点击:

Error when trying to connect to Oracle 10g database from C# program employing minimal set-up configuration

c#oracleclickonceoracleexception

提问by steve

I'm experiencing an error when trying to connect to a remote Oracle 10g database from a C# 2008 Express Edition application I'm developing. I'm trying to use a minimalist, non-intrusive approach to the development with a view to ClickOnce deployment to user workstations.

我在尝试从我正在开发的 C# 2008 Express Edition 应用程序连接到远程 Oracle 10g 数据库时遇到错误。我正在尝试使用极简、非侵入式的开发方法,以期将 ClickOnce 部署到用户工作站。

In respect of the above I've investigated the following documents (amongst others..) -

就上述而言,我调查了以下文件(其中包括..)-

What is the minimal setup required to deploy a .NET application with Oracle client 11?

使用 Oracle 客户端 11 部署 .NET 应用程序所需的最少设置是什么?

http://jeremybranham.wordpress.com/2011/04/25/oracle-instant-client-with-odp-net/

http://jeremybranham.wordpress.com/2011/04/25/oracle-instant-client-with-odp-net/

http://ora-00001.blogspot.com/2010/01/odpnet-minimal-non-intrusive-install.html

http://ora-00001.blogspot.com/2010/01/odpnet-minimal-non-intrusive-install.html

http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c

http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c

Connect to Oracle with odp.net and the OCI from C#

使用 odp.net 和 C# 中的 OCI 连接到 Oracle

In view of the error I've experienced I've created a simple test app. consisting of a single (wpf) page with one button. In the click-event of the button I attempt to create a connection to an Oracle database -

鉴于我遇到的错误,我创建了一个简单的测试应用程序。由一个按钮的单个 (wpf) 页面组成。在按钮的单击事件中,我尝试创建与 Oracle 数据库的连接 -

private void button1_Click( object sender, RoutedEventArgs e )
{
    OracleConnection oraConnect;

    // string previously used OK in other projects
    string connectionString = "Data Source=" +
           "(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = myServer)(PORT = 1521)))" +
           "(CONNECT_DATA =(SERVICE_NAME = myOracleDb)))" +
           ";Password=myPw;User ID=myID;";

    using ( oraConnect = new OracleConnection( connectionString ) )
    {
        try
        {
            if ( oraConnect.State == ConnectionState.Closed )
            {
                oraConnect.Open();
                MessageBox.Show( "oraConnect is attempting to open.." );
            }
            else
                MessageBox.Show( "oraConnect open to DB: " + oraConnect.ServerVersion.ToString() );
        }
        catch ( NullReferenceException nullExcept )
        {
            MessageBox.Show( "Caught error: ." + nullExcept.ToString() );
        }
        catch ( OracleException dbEx )
        {
            MessageBox.Show( "OraException - " + dbEx.Message.ToString());
        }
        catch ( Exception ex )
        {
            Exception current;
            current = ex;

            while ( current != null )
            {
                current = current.InnerException;
            }

            MessageBox.Show( "Db base exception - " + ex.GetBaseException().ToString() );
        }
        finally
        {
            oraConnect.Close();
        }
    }
}

Following the information in the above articles I've ensured that the following Dll's are in my "bin" folder -

按照上述文章中的信息,我确保以下 Dll 位于我的“bin”文件夹中 -

? oci.dll
? ociw32.dll
? orannzsbb10.dll
? oraocci10.dll
? oraociicus.dll
? msvcr71.dll

? oci.dll
? ociw32.dll
? orannzsbb10.dll
? oraocci10.dll
? oraociicus.dll
? msvcr71.dll

(the last named in desperation...) and have referenced 'Oracle.DataAccess.dll'.

(最后在绝望中命名......)并引用了'Oracle.DataAccess.dll'。

The error message (at 'catch ( OracleException dbEx )') is -

错误消息(在 'catch ( OracleException dbEx )' 处)是 -

"Oracle.DataAccess.Client.OracleException was caught
  Message=""
  StackTrace:
       at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
       at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
       at Oracle.DataAccess.Client.OracleConnection.Open()
       at OracleConnectionTest.Window1.button1_Click(Object sender, RoutedEventArgs e) in C:\Documents\Visual Studio 2008\Projects\OracleConnectionTest\OracleConnectionTest\Window1.xaml.cs:line 69
  InnerException: "

Line 69 is 'oraConnect.Open();'.

In addition, the following is reported -

此外,报告如下——

"((Oracle.DataAccess.Client.OracleException)($exception)).DataSource' threw an exception of type 'System.NullReferenceException".

I'm assuming from the NullReferenceException within the datasource that the problem lies in one of the dlls' (?) as I 'new' the OracleConnection above before trying to reference it.

我从数据源中的 NullReferenceException 假设问题出在 dll 之一(?)中,因为我在尝试引用它之前“新建”了上面的 OracleConnection。

In addition, the code execution jumps the 'catch ( NullReferenceException nullExcept )' and goes straight to the OracleException catch.

此外,代码执行会跳转到“catch (NullReferenceException nullExcept)”并直接进入 OracleException catch。

Sorry for rambling on but hope this makes sense? Any help/advice appreciated!

抱歉我胡说八道,但希望这是有道理的?任何帮助/建议表示赞赏!

回答by steve

OK, very late getting back to this for which many apologies!

好的,很晚才回到这一点,为此深表歉意!

In the interim, our DB has been upgraded(!) and in changing the dll list to include -

在此期间,我们的数据库已升级(!)并更改了 dll 列表以包括 -

  • oraocci11.dll
  • oraociccus11.dll
  • OraOps11w.dll
  • orannzsbb1.dll
  • oraocci11.dll
  • oraociccus11.dll
  • OraOps11w.dll
  • oranzsbb1.dll

from the '10' versions, still with no success, I edited App.xaml (following an extensive search here and on the web) with the following -

从“10”版本中,仍然没有成功,我编辑了 App.xaml(在此处和网络上进行了广泛搜索),其中包含以下内容 -

    <system.data>
      <DbProviderFactories>
         <add name="OracleClient Data Provider"
              invariant="System.Data.OracleClient"
              description=".Net Framework Data Provider for Oracle"
              type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=##################"/>
      </DbProviderFactories>
   </system.data>

   <!-- publicKeyToken obtained using Reflector to investigate dll -->
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="Oracle.DataAccess"
                              publicKeyToken="##################"
                              culture="neutral"/>
            <bindingRedirect oldVersion="10.2.0.100" 
                             newVersion="2.112.2.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>

The bindingRedirect did the trick!

bindingRedirect 成功了!

The dll's appear to be extremelydependent on compatible version numbers

dll 似乎非常依赖于兼容的版本号

Wish I could say I really understood howthis works but it does and I now have working connections...

希望我能说我真的理解这是如何工作的,但它确实如此,而且我现在有工作联系......

回答by Zonko

It happened to me.

它发生在我身上。

After a bit of voodoo, I deleted this key from my registery : HKEY_CURRENT_USER\Software\ORACLEand everything worked fine again.

经过一番伏都教之后,我从我的注册表中删除了这个密钥:HKEY_CURRENT_USER\Software\ORACLE一切又正常了。

回答by tbone

Make sure ODAC is setup properly. I would suggest to use TNSNAMES (you shouldn't have all that info in a connection string imo). See the TNSNAMES setupsection of this document (11.2). Also see bottom section for common connection issues

确保正确设置 ODAC。我建议使用 TNSNAMES (您不应该在连接字符串中包含所有这些信息 imo)。请参阅本文档 (11.2)的TNSNAMES 设置部分。另请参阅底部以了解常见的连接问题

Once that's done, it should be as easy as putting your connection string in the settings property of your project and doing:

完成后,应该就像将连接字符串放在项目的设置属性中并执行以下操作一样简单:

oraConnect = new OracleConnection(Properties.Settings.Default.MyConnString);

In your example, your oraConnect hasn't been instantiated (you just have "OracleConnection oraConnect"), so the "new OracleConnection" part that fails results in a null reference exception (if I understand your explanation of where its breaking anyway). Debugger in VS should help here as well ;)

在您的示例中,您的 oraConnect 尚未实例化(您只有“OracleConnection oraConnect”),因此失败的“新 OracleConnection”部分会导致空引用异常(如果我理解您对它在哪里中断的解释)。VS 中的调试器在这里也应该有所帮助;)

EDIT: You may want to setup a simple test console app with just open/close connection. This might eliminate any noise other than getting your ODAC setup properly. Something like (untested, assume tnsnames setup):

编辑:您可能想要设置一个简单的测试控制台应用程序,只需打开/关闭连接。除了正确设置 ODAC 之外,这可能会消除任何噪音。类似(未经测试,假设 tnsnames 设置):

using ...

使用 ...

namespace Testbed {
  class Program {
    static void Main(string[] args) {
      try {
        string connStr="User Id=my_user;Password=my_pass;Data Source=my_sid;";
        OracleConnection oraConnect = new OracleConnection(connStr);
        oraConnect.Open();
        Console.WriteLine("Opened Connection");
        oraConnect.Close();
        Console.WriteLine("Complete");
        Console.ReadLine();
      catch (System.Exception e) {
        Console.WriteLine(e.Message);
        Console.ReadLine();
      } ...

Try running that and report what comes back from console.

尝试运行它并报告从控制台返回的内容。