2009-06-25 19 views
16

ile ada göre sorgu parametrelerini bağlama Oracle (System.Data.OracleClient) için Microsoft ADO.NET sağlayıcısı kullanıyorum. Bunun en iyi Oracle sağlayıcısı olmadığını ve bunun will soon be deprecated olduğunu bilmekteyim, bunun yerine Oracle'ın ODP.NET'ini kullanmalıyım. MS sağlayıcısını hala kullanmamın nedeni, ODP.NET parametresinin parametreleri, isimle değil, numaralı konuma göre bağlamasıdır. Bu, bir sorguda birçok parametre kullandığınızda gerçekten bir PITA olabilir, çünkü bunları doğru sıraya eklemeye dikkat etmeniz gerekir; bu da kolayca hatalara neden olabilir.ODP.NET

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

, ben aptal olduğunu düşünüyorum OracleCommand, iki parametre eklemek zorunda ...

: Eğer Mesela aynı sorguda aynı parametreyi birden çok kez kullandığınızda Ayrıca sinir bozucu

ODP.NET'in OracleCommand varsayılan davranışını değiştirmek için bir özelliğe sahiptir: BindByName. Doğru olarak ayarlandığında, parametreler istediğim addır. Maalesef bu gerçekten bana yardımcı olmuyor:

  • Ben neredeyse somut ADO.NET sınıflarını açıkça kullanmak asla
  • varsayılan olarak false olarak ayarlanır, ben DbProviderFactory (ADO.NET 2.0 soyutlama katmanı kullanmayı tercih Herhangi bir belirli RDBMS'ye bağlantıyı azaltmak için, DbConnection, DbCommand ...). Bu nedenle, BindByName özelliğine, OracleCommand'a açıkça izin vermedikçe, tüm avantajları veya soyutlamayı kaybetmeden erişemiyorum.
  • Bir ASP.NET SqlDataSource kullanıldığında, kendim DbCommand'ı oluşturmadım, bu yüzden BindByName değerini true olarak ayarlama şansım yok (bunu Selecting olayında yapabilirim, ancak gerçekten bir her SqlDataSource için yapın ...)

Bu sorunu nasıl ele alabilirim? Bir yerde BindByNameByDefault ayarı var mı? (Ben böyle bir şey bulamadık, ama onu kaçırmış olabilir ...)

+0

Bu "özellik" nedeniyle 3 saat harcadım! – Grzenio

cevap

7

Sana kullanmak istediğiniz varsayılan değerleri kullanır kendi sağlayıcı oluşturabilirsiniz düşünüyorum. Bütün sınıfları odp.net'ten devralarak bu sağlayıcıyı kolayca oluşturabilir, sadece BindByName gibi bazı özellikleri ayarlayabilirsiniz.

DbProviderfactory, normal odp.net sınıfları yerine sınıflarınızı oluşturacaktır. Oracle için Microsoft ADO .NET sağlayıcı kesilmesine gelince

+0

İyi fikir, teşekkürler! Ben bu –

+2

denemek düşünüyorum, bu mümkün görünüyor, ama çok basit değil ... çoğu ODP.NET sınıfları mühürlü, bu yüzden yöntemleri geçersiz kılmak için onlardan miras ve yapamam, Reflektör göre orada birçok yerde OracleCommand yapıcısı açıkça denir ... Neyse, daha iyi bir çözüm düşünemiyorum, bu yüzden cevabınızı kabul ediyorum. Teşekkürler ! –

1

: Ben bunu kullanarak yerine ODP .NET devam edecek

  • , senin sorunun onunla sayısız konulardan sadece biri olma. Ve devam ettikçe, desteklenemese de .NET 4.0'da hala kullanılabilir olacak.
  • Oracle bu sağlayıcıyı kullanılamaz hale getirmeyi başarırsa, muhtemelen ADO .NET çerçevesine tam olarak entegre olan DataDirect ADO.NET Data Provider for Oracle veya dotConnect for Oracle gibi ticari bir alternatifle gideceğim. Ve onlar zaten yol (I Oracle ODP .NET olmaz belirtti inanmak) tarafından, Varlık Framework desteklemektedir.

ODP .NET zaten zamanımın çok fazla sürdü.

+0

Muhtemelen üçüncü taraf sağlayıcılar hakkında haklısınız, ancak özgür değiller, bu yüzden işverenimi onları satın almaya ikna edebileceğime emin değilim ... Ancak Entity Framework desteği dengedeki ciddi bir argümandır. . Oracle'ın neden Oracle'da uygulamadığını anlamıyorum ... –

+0

Oracle için dotConnect'i şiddetle tavsiye ediyorum. Bunun için ödediğiniz her dolar değerindedir. – Konamiman

+0

Oracle aslında Entity Framework'ü desteklemeye başladı, şu anda EF ve Linq desteği ile beta ODP.net sürümü var. – Tridus

4

Kullanım indirection ve devralma! Eğer soyut bir veritabanı sınıfı aracılığıyla veri erişimini yorumu yapıyorsanız bağlama Veritabanı uygulama kolu parametresini gerektirir.

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) 
    { 

    } 
} 

Ve varsayılan komut oluşturma geçersiz kılar veya adıyla parametreleri bağlamak için seçenek sunar Oracle belirli uygulama oluşturmak için seçin. Enterprise Library yılında Data Access Application Block dayalı

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

Kodu.

+0

Bu, bir proje için yaptığım şeye çok benziyor. OracleDatabase sınıfı, ODP.NET varsayılan uygulamasının sağlamadığı kolaylık yöntemleri eklemek için de güzel bir uzantı noktası sağlar. – CodingWithSpike

+0

Bu çözüm C# kodunda kullanım için mükemmel olsa da, bir ASP.NET SqlDataSource durumunda yardımcı olmaz: Bir ADO.NET sağlayıcısını belirtmem gerekiyor, özel bir veri erişim katmanı değil ... –

+0

@Thomas Levesque SqlDataSource'a aşina değilim, ama DataSourceControl'den miras alabiliyor ve kendi OracleDataSource'unuzu yeniden oluşturabiliyorsunuz. –