ODAC 10からODAC 12への移行

皆さんおはようございます!



ここでは、.NetプロジェクトでOracle.DataAcess 12番目のバージョンにすばやく切り替える必要がありました。 そして、アプリケーションを開始しようとした瞬間まで、すべてがうまくいきました。 数千の場所で、次のようなエラーが発生します。



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







フォーラムでの検索で答えが得られました。11番目のバージョンでは、OracleParameterで何かを具体的にリプレイしたため、プロジェクトのすべてのConvert.ToXXXが落ちました。

解決策として、Mark Williamsブログoradim.blogspot.ru/2009/08/odpnet-vb-and-from-type-to-type-is-not.htmlは次のことを示唆しています。



「出力」または「戻り値」でコードに変換の問題がある場合、OracleDbType vs. DbTypeは、.NET Framework型またはOracleプロバイダー型が返されるかどうかを決定します。 また、現在のODP.NET Beta(11.1.7.10)は、Oracleパラメータクラスの新しいプロパティを公開しています。OracleDbTypeExこのプロパティを使用すると、OracleDbTypeを使用して値をバインドできますが、.NETタイプとして値を返します。




自動的に、このプロパティは初期化されません。 次の部分は、dotPeekを介してODACの内部で発見されました。



  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; } }
      
      







つまり 必須プロパティはパラメータコンストラクタ自体から初期化されないため、this.m_bOracleDbTypeExSetフィールドがtrueになるように、その設定をコードに明示的に追加する必要があります。

OracleCommandの拡張メソッドを備えた独自のライブラリがすでにあり、別のメソッドを追加したため、膨大な数のチーム宣言を削減したくはありませんでした。



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







そして、ExecuteNonQueryExtとbingoのExecuteNonQueryプロジェクトのオートコレクト! すべてが起動して飛びました。 :-)

おそらく、プロジェクトの半分を書き直さずにこの移行を完了するためのより簡単な方法がありますが、フォーラムで解決策が見つかりませんでした。 レーキは非常に古く、多くは第11バージョンのリリース時にそれらを踏んでいました。



All Articles