私たちのアプリケーションは、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);
}
}
これが正しい方法なのか、それとも他の洗練された回避策が既に利用可能なのかはわかりません。しかし、それはうまくいきました。