Migrating from ODAC 10 to ODAC 12

    Good morning everyone!

    We needed here to quickly switch to Oracle.DataAcess 12th version in our .Net project. And everything went fine right up until the moment we tried to start the application. In a couple of thousand places, an error like:

    Unable to cast object of type 'Oracle.DataAccess.Types.OracleDecimal' to type 'System.IConvertible'.
    


    The search in the forums gave the answer - in the 11th version something was specifically outplayed in OracleParameter and as a result - all Convert.ToXXX in our project fell off.
    As a solution, the Mark Williams blog oradim.blogspot.ru/2009/08/odpnet-vb-and-from-type-to-type-is-not.html suggests the following:

    If you are having conversion problems in your code with "output" or "return values" keep in mind that setting OracleDbType vs. DbType will determine whether a .NET Framework type or an Oracle provider type is returned. Also, the current ODP.NET Beta (11.1.7.10) exposes a new property for the Oracle Parameter class: OracleDbTypeEx This property allows you to bind values ​​using the OracleDbType but will return values ​​as .NET types.


    Automatically, this property is not initialized. The following piece was discovered in the internals of ODAC through dotPeek:

        public OracleDbType OracleDbType
        {
          get
          {
            return this.m_oraDbType;
          }
          set
          {
            if (this.m_oraDbType != value)
            {
              OracleDbType oracleDbType = value;
              if (oracleDbType < OracleDbType.BFile || oracleDbType > OracleDbType.Boolean)
                throw new ArgumentOutOfRangeException();
              this.m_oraDbType = oracleDbType;
            }
            this.m_bSetDbType = false;
            this.m_enumType = PrmEnumType.ORADBTYPE;
            this.m_bOracleDbTypeExSet = false;
          }
        }
     public OracleDbType OracleDbTypeEx
        {
          get
          {
            return this.m_oraDbType;
          }
          set
          {
            this.OracleDbType = value;
            this.m_bOracleDbTypeExSet = true;
          }
        }
    


    Those. the desired property from the parameter constructor itself is not initialized; you need to explicitly add its setting to the code so that this.m_bOracleDbTypeExSet field becomes true.
    We decidedly didn’t want to cut a huge number of team declarations, since we already had our own library with extension methods for OracleCommand and we added another method:

    public static int ExecuteNonQueryExt(this OracleCommand cmd)
            {
                foreach (OracleParameter param in cmd.Parameters)
                {
                    param.OracleDbTypeEx = param.OracleDbType;
                }
                return cmd.ExecuteNonQuery();
            }
    


    And then AutoCorrect for the ExecuteNonQuery project at ExecuteNonQueryExt and bingo! Everything started up and flew. :-)
    Perhaps there is some more painless way to complete this transition without rewriting half the project, but it was not possible to find a solution on the forums. Although the rake is quite old and many stepped on them at the time of the release of the 11th version.

    Also popular now: