1

私たちのアプリケーションは、Enterprise Library DAAB を使用して、oracle データベースと sql データベースの両方をサポートしています。

ストアド プロシージャの 1 つは、イメージをテーブルにアップロードするためのものです。これは BLOB フィールドで、パラメーターは DbType.Binary に設定されています。

この機能は SQL では問題なく動作しますが、Oracle に関しては、32K のパラメーター サイズ制限の問題にぶつかりました。

SOで提案されているように、コードをODP.NETに移動しましたが、まだ同じ問題に直面しています。

私の App.config ファイル設定:

<configuration>
<configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<dataConfiguration defaultDatabase="Oracle">
    <providerMappings>
        <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
            name="Oracle.DataAccess.Client" />
    </providerMappings>
</dataConfiguration>
<connectionStrings>
    <add name="Oracle" connectionString="Data Source=MYORACSER;USER ID=UNAME;PASSWORD=MYPWD;"
        providerName="Oracle.DataAccess.Client" />
</connectionStrings>

私のアプリケーション コードでは、エンタープライズ ライブラリを使用して DB にアクセスしています

 Database db = DatabaseFactory.CreateDatabase(); 
 DbCommand cmd = db.GetStoredProcCommand(spName);
 cmd.CommandType = CommandType.StoredProcedure;
 db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath));
 db.AddOutParameter(cmd, "return_value", DbType.Int32, 128);
 int row = db.ExecuteNonQuery(cmd);

プロジェクトで次のアセンブリを参照しています。

ここに画像の説明を入力

アプリケーションを実行すると、Ent Lib DAAP は Oracle.DataAccess.Client を使用するはずですが、System.Data.OracleClient を介して oracle db に接続されています。したがって、32K の制限はまだあります。

ここに画像の説明を入力

App.configで明確に述べたように、Oracle Data Providerを使用していないのはなぜですか?

ある投稿では、回避策として次のスニペットを使用することが言及されています。

DbProviderFactory providerFactory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
Database db = GenericDatabase(connectionString, providerFactory); 

これは機能しているようです。

ここに画像の説明を入力

ただし、インスタンス化されたデータベースは、OracleDatabase ではなく GenericDatabase のものです。そのため、ファイル サイズが 32K を超えると、この回避策でも例外がスローされる可能性があります。

32Kのサイズ制限の問題に対してEnterprise LibraryでODP.NETを使用するにはどうすればよいですか?

解決済み:

hridyaウォークスルーをたどりました。彼が言及したように、XML コメント エラーがありましたが、これは無効にすることができます(ここを参照)。また、名前空間の競合がいくつかありましたが、Oracle.DataAccess.Client を選択することで解決されました。これらの後、正常にコンパイルされました。

以下は、変更をテストするために作成したサンプル アプリケーションのコード スニペットです。(サンプル ソリューションは、新しくコンパイルされたデータと共通の dll を参照するようになりました。)

Database db = DatabaseFactory.CreateDatabase();
            DbCommand cmd = db.GetStoredProcCommand(sqlCode);
            cmd.CommandType = CommandType.StoredProcedure;
            db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath));
            db.AddOutParameter(cmd, "return_value", DbType.Int32, 128);
            int rowID = db.ExecuteNonQuery(cmd);

コマンド オブジェクトを確認しました。以前は System.Data.OracleClient.OracleCommand でしたが、現在は Oracle.DataAccess.Client.OracleCommand 型になっています。

ODP.NET を使用するように DAAB を既に変更しているため、providerMappings タグを使用して構成ファイルでプロバイダーを明示的に設定する必要がないことを思い出してください。

しかし、ファイル サイズが 32K を超えると、まだ同じエラーが発生します。適切な OracleDbType に変更されませんでした。

それを機能させるために、Enterprise Lib のデータ プロジェクトにコード修正をもう 1 つ追加しました。

ファイル: \Oracle\OracleDatabase.cs

メソッド: AddParameter

元のコード:

public override void AddParameter(DbCommand command, string name, DbType dbType, int size,
        ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn,
        DataRowVersion sourceVersion, object value)
    {
        if (DbType.Guid.Equals(dbType))
        {
            object convertedValue = ConvertGuidToByteArray(value);

            AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, convertedValue);

            RegisterParameterType(command, name, dbType);
        }
        else
        {
            base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale,
                sourceColumn, sourceVersion, value);
        }
    }

DbType.Binary の条件を追加

変更されたコード:

public override void AddParameter(DbCommand command, string name, DbType dbType, int size,
        ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn,
        DataRowVersion sourceVersion, object value)
    {
        if (DbType.Guid.Equals(dbType))
        {
            object convertedValue = ConvertGuidToByteArray(value);

            AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, convertedValue);

            RegisterParameterType(command, name, dbType);
        }
        else if(DbType.Binary.Equals(dbType))
        {
            AddParameter((OracleCommand)command, name, OracleDbType.Blob, size, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, value);

        }
        else
        {
            base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale,
                sourceColumn, sourceVersion, value);
        }
    }

これが正しい方法なのか、それとも他の洗練された回避策が既に利用可能なのかはわかりません。しかし、それはうまくいきました。

4

2 に答える 2

1

次の手順で正しい結果が得られることを願っています。

System.Data.OracleClient を Oracle.DataAccess.Client に置き換えるには; および Oracle.DataAccess.Types

Microsoft Enterprise Library バージョン 3.1 の最新バージョンをダウンロードしてインストールします

Oracle Web サイトから Oracle ODP.Net をダウンロードしてインストールします。DLL ファイルは C:\oracle\product\11.1.0\client_1\odp.net\bin\2.x\Oracle.DataAccess.dll にあります。

ソースをインストールするように求められたら、チェックボックスを使用してインストールします。

その後、パス C:\Program Files\Microsoft Enterprise Library 3.1 - May 2007\src で msi を実行しなかった場合

ライブラリのコードは、パス C:\EntLib3Src\App Blocks に保存されます。

後で必要になった場合に備えて、元の src フォルダーのバックアップを作成します - C:\EntLib3Src\App Blocks\Src

ソリューション ファイル EnterpriseLibrary.sln を開き、Data Access Application Block の下のデータ プロジェクトに移動します。

Oracle.DataAccess.dll 参照をデータ プロジェクトに追加します。DLL ファイルは次の場所にある必要があります:- C:\oracle\product\11.1.0\client_1\odp.net\bin\2.x\Oracle.DataAccess.dll

以下を検索して置き換えます [代わりに、この記事に添付されている更新された DLL をダウンロードして使用できます]

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
ファイル:- C:\EntLib3Src\App Blocks\Src\Data\DatabaseConfigurationView.cs
ファイル:- C:\EntLib3Src\App Blocks\Src \Data\Oracle\OracleDataReaderWrapper.cs

検索:-using System.Data.OracleClient;
置換:-using Oracle.DataAccess.Client; using Oracle.DataAccess.Types;

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Configuration\DbProviderMapping.cs クラス:- DbProviderMapping

検索:-System.Data.OracleClient
置換:-Oracle.DataAccess.Client

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Configuration\Manageability\ ConnectionStringsManageabilityProvider.cs
メソッド:-AddAdministrativeTemplateDirectives
検索:-System.Data.OracleClient
置き換え:-Oracle.DataAccess.Client

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
メソッド:-AddParameter

探す :-public void AddParameter(OracleCommand command, string name, OracleType oracleType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)

と置換する:-public void AddParameter(OracleCommand command, string name, OracleDbType oracleType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)

理由:- OracleType は、odp.net API のタイプ名として、3 番目のパラメーターとして OracleDbType に置き換えられました。

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
削除:- [OraclePermission(SecurityAction.Demand)]-

誰かがフィードバックセッションについて簡単に説明してください。

ファイル:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
検索:-OracleType.Raw
置換:-OracleDbType.Raw

検索:-param.OracleType
置換:-param.OracleDbType

検索:-OracleType.Cursor
置換:-OracleDbType.RefCursor

検索:-parameter.OracleType
置換:-parameter.OracleDbType

今すぐコンパイルし、エラーが発生した場合は、エラーとして次の警告を実行します: XML コメント オン - 強調表示されたエラー コンテンツを削除する / 適切なコメントに置き換えてください。

上記のプロジェクトをコンパイルして生成された DLL は、SqlServer と Oracle の両方に対して使用できるようになりました [ODP.Net]

于 2012-11-13T05:33:02.903 に答える
1

これは少し遅れましたが、レスポンダーが EL3.1 の使用を提案した正当な理由がわかりません。これは非常に時代遅れです - 5 は最新バージョンです (そして、この記事の前にほぼ 2 年間出ていました)。 OPはコードサンプルによると4.1を使用していました。EL5でODPを使用する方がはるかに簡単です(EntlibContribプロジェクトを利用して私自身がそうしました)。BLOBを使用しないため、パラメーターサイズに関する潜在的な問題について話すことはできませんが、EntlibContribはOracleDbTypeの使用をネイティブに許可するので、私は思うおそらく問題ないでしょう。

EL5 と ODP を最小限の労力で適切に動作させる方法を疑問に思っている人がこの投稿に出くわした場合に備えて、詳細を提供できます。

于 2013-02-20T16:29:03.027 に答える