2009-06-25 27 views
16

現在、Oracle用のMicrosoft ADO.NETプロバイダ(System.Data.OracleClient)を使用しています。私はそれが確かに利用可能な最高のOracleプロバイダではないとそれはwill soon be deprecated、私はOracleのODP.NETを代わりに使用する必要があります知っている。私がまだMSプロバイダーを使用している理由は、ODP.NETは、名前ではなく位置でパラメーターをバインドするためです。これは、正しい順序で追加することに注意する必要があるため、クエリで多くのパラメータを使用するとPITAになる可能性があり、バグにつながる可能性があります。ODP.NETで名前でクエリパラメータをバインドする

ODP.NETで
SELECT A,B,C FROM FOO WHERE X = :PARAM_X OR :PARAM_X = 0 

、私は私が愚かだと思うOracleCommandに2つのパラメータを追加する必要があり...

:あなたは、たとえば、同じクエリで同じパラメータを複数回使用する場合にも迷惑なんです

ODP.NETのOracleCommandには、このデフォルト動作を変更するプロパティがあります。BindByName。 trueに設定すると、パラメータは名前でバインドされます。これは必要なものです。残念ながら、これは本当に、私を助けていません:

  • それは、私はほとんど明示的に具体的なADO.NETクラスを使用することはありません
  • デフォルトでfalseに設定されている、私はDbProviderFactory(ADO.NET 2.0抽象化レイヤを使用することを好みます、DbConnectionDbCommand ...)を使用して、特定のRDBMSへの結合を減らします。したがって、プロパティにアクセスすることはできません。明示的にOracleCommandにキャストしない限り、すべてのメリットまたは抽象化が失われます。
  • ASP.NET SqlDataSourceを使用しているときは、自分でDbCommandを作成しないため、BindByNameをtrueに設定する機会はありません(選択イベントでも可能ですが、本当に苦痛です各SqlDataSourceでそれを行います...)

どうすれば問題を処理できますか?どこかでBindByNameByDefaultの設定がありますか? (私はそのようなものは見つけられませんでしたが、私はそれを見逃したかもしれません...)

+0

この「機能」のために、私はただ3時間を無駄にしました! – Grzenio

答えて

7

私はあなたが使用したいデフォルトを使用する独自のプロバイダを作成できると思います。 odp.netからすべてのクラスを継承することで簡単にそのプロバイダを作成できます。BindByNameのようなプロパティを調整するだけです。

DbProviderfactoryは、通常のodp.netクラスの代わりにクラスを作成します。 Oracle用のMicrosoft ADO .NETプロバイダの中止については

+0

良いアイデア、ありがとう!私はそれを試みると思う –

+2

OK、それは実現可能なようだが、非常に簡単ではない...ほとんどのODP.NETクラスは封印されているので、メソッドをオーバーライドするためにそれらを継承することはできず、リフレクターによれば、 OracleCommandのコンストラクタは明示的に呼び出されます...とにかく、私はより良い解決策は考えられませんので、私はあなたの答えを受け入れます。ありがとう! –

1

:私はそれを使用しての代わりに、ODP .NETに行く

  • 、あなたの問題は、それを持つ数多くの問題の唯一の一つです。また、サポートされていないにもかかわらず、.NET 4.0でも利用可能になります。
  • Oracleがこのプロバイダを使用不能にすると、DataDirect ADO.NET Data Provider for OracleまたはdotConnect for OracleなどのADO .NETフレームワークに完全に統合された商用の代替製品が使用される可能性があります。そして、彼らはすでにEntity Frameworkをサポートしています(私はOracleがODP .NETにはないと信じています)。

ODP .NETはすでに自分の時間を過ごしました。

+0

あなたはおそらくサードパーティのプロバイダについては正しいかもしれませんが、彼らは無料ではないので、私は雇用主にそれらを購入することを納得させることができません...しかし、Entity Frameworkのサポートは、 。オラクルがODP.NETでそれを実装していない理由を理解できません。 –

+0

Oracle用のdotConnectを強くお勧めします。あなたが支払う1ドルの価値があります。 – Konamiman

+0

OracleはEntity Frameworkを実際にサポートし始めました。現在ODF.netのベータ版がリリースされており、現在EFとLinqのサポートがあります。 – Tridus

4

間接参照と継承を使用してください。抽象データベースクラスを介してデータアクセスを実行する場合は、データベース実装のハンドルパラメータバインディングが必要です。

public abstract class Database 
{ 
    private readonly DbProviderFactory factory; 

    protected Database(DbProviderFactory factory) 
    { 
     this.factory = factory; 
    } 

    public virtual DbCommand CreateCommand(String commandText) 
    { 
     return CreateCommand(CommandType.Text, commandText); 
    } 

    public virtual DbCommand CreateCommand(CommandType commandType, String commandText) 
    { 
     DbCommand command = factory.CreateCommand(); 
     command.CommandType = commandType; 
     command.Text = commandText; 
     return command; 
    } 

    public virtual void BindParametersByName(DbCommand command) 
    { 

    } 
} 

、デフォルトのコマンドの作成を上書きしたり、名前でパラメータをバインドするためのオプションを提供するOracle固有の実装を作成することを選択しました。

public class OracleDatabase : Database 
{ 
    public OracleDatabase() 
     : base(OracleClientFactory.Instance) 
    { 

    } 

    public override DbCommand CreateCommand(CommandType commandType, String commandText) 
    { 
     DbCommand command = base.CreateCommand(commandType, commandText); 
     BindParametersByName(command); 
     return command; 
    } 

    public override void BindParametersByName(DbCommand command) 
    { 
     ((OracleCommand)command).BindByName = true; 
    } 
} 

Enterprise LibraryData Access Application Blockに基づいてコード。

+0

これは私がプロジェクトでやったことに非常に似ています。 OracleDatabaseクラスは、ODP.NETのデフォルト実装では提供されない便利なメソッドを追加するための優れた拡張ポイントも提供します。 – CodingWithSpike

+0

このソリューションはC#コードでの使用には最適ですが、ASP.NET SqlDataSourceの場合は役に立ちません。カスタムデータアクセスレイヤではなくADO.NETプロバイダを指定する必要があります。 –

+0

@Thomas Levesque私はSqlDataSourceに慣れていませんが、DataSourceControlから継承し、独自のOracleDataSourceを再構築することができます。 –

関連する問題