2012-04-11 26 views
13

Jakie są główne zalety każdej z powyższych metod połączenia z bazą danych w języku C# pod względem łączenia się z wieloma możliwymi źródłami danych (jako agnostykiem bazy danych)? Również pod względem wydajności, która może zapewnić najlepszą wydajność we wszystkich dziedzinach?DbConnection vs OleDbConnection vs OdbcConnection

Wreszcie, czy są jakieś powody, dla których można by uniknąć konkretnej metody dla agnostycznej aplikacji bazy danych?

Powodem, dla którego pytam, jest to, że moja aplikacja obecnie używa Ole i mam kilka problemów z łączeniem się z pewnymi bazami danych za pomocą fabryk i jako takie szukam alternatyw. Słyszałem, że Odbc jest wolniejszy niż Ole, ale czy jest za tym jakaś prawda i czy jest naprawdę zauważalna w prawdziwym świecie?

Powód mojego zainteresowania w tej sprawie jest następujące:

moje wymagania dla mojego obecnego stanu projektu, że muszę mieć pracę warstwę dostępu do danych, które są zdolne do podłączenia do dowolnej bazy danych bez uprzedniej znajomości powiedział Baza danych. Dlatego nie mogę napisać nic konkretnego dla danej bazy danych pod względem połączenia. Uruchamianie specyficznych instrukcji dialektu dla każdej bazy danych zostało rozwiązane przy użyciu koncepcji typu fabryki zapytań sql. To samo dotyczy podstawiania i formatowania zmiennych wiązania.

AKTUALIZACJA: W obecnej wersji mam działającą wersję mojego kodu, który wykorzystuje ADO.net i fabryki dostawców baz danych. Oznacza to, że używam klas bazowych zgodnie z sugestią Adama Houldswortha. Dostawca jest określony w ciągu połączenia pod atrybutem providerName. Ciąg połączenia jest przechowywany w pliku app.config, gdzie można go pobrać przez moją klasę połączenia z bazą danych. Pod warunkiem, że został zainstalowany odpowiedni sterownik, taki jak npgsql lub pakiet odac dla Oracle, wtedy fabryka będzie działać poprawnie. Poniżej znajduje się przykład mojego kodu pokazujący podstawowy konstruktor obiektu połączenia przy użyciu fabryki dostawców.

private readonly DbFactoryBindVariables m_bindVariables; 
private readonly DbProviderFactory m_provider; 
private string m_connectionString = String.Empty; 
private readonly string m_providerName = String.Empty; 
private DbConnection m_dbFactoryDatabaseConnection; 


/// <summary> 
/// Default constructor for DbFactoryDatabaseConnection. 
/// </summary> 
public DbProviderFactoryConnection() 
{ 
     m_providerName = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ProviderName; 
     m_provider = DbProviderFactories.GetFactory(m_providerName); 

     m_dbFactoryDatabaseConnection = m_provider.CreateConnection(); 

     m_connectionString = ConfigurationManager.ConnectionStrings["ApplicationDefault"].ConnectionString; 
     m_dbFactoryDatabaseConnection.ConnectionString = m_connectionString; 

     m_bindVariables = new DbFactoryBindVariables(m_dialect.ToLower(), DbFactoryBindSyntaxLoader.Load(this)); 
} 

To może być wymagane, aby dodać coś podobnego do następującego w app.config lub web.config, jeśli nie jest już obecna w machine.config dla wybranej wersji .NET Framework.

<system.data> 
    <DbProviderFactories> 
     <add name="Npgsql Data Provider" 
     invariant="Npgsql" 
     support="FF" 
     description=".Net Framework Data Provider for Postgresql Server" 
     type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.1.0, Culture=neutral, 
     PublicKeyToken=5d8b90d52f46fda7" /> 
    </DbProviderFactories> 
</system.data> 

ciąg połączenia wymagane:

<add name="ApplicationDefault" connectionString="DATA SOURCE=TNSNAME;PASSWORD=PASS;USER ID=USER;" providerName="Oracle.DataAccess.Client;"/> 

Na tym etapie mogę teraz być całkowicie niezależne od bazy danych pod warunkiem prawidłowego ciąg połączenia jest używany podczas konfigurowania wersji klientów aplikacji.

+0

Dodano aktualizację dla zainteresowanych. – CSharpened

Odpowiedz

5

Unikałbym abstrakcyjnego połączenia z bazą danych, ponieważ zawsze celujesz w najniższy wspólny mianownik. Zamiast tego spróbuj wyodrębnić wymóg zachowania jednostek. Każda implementacja tej abstrakcji może być specyficzna dla bazy danych (w zasadzie programowanie w oparciu o interfejsy).

Powiedziałem, że nie spotkałem się z żadną instancją, w której wymaganie obsługi wielu baz danych było trudne. W tym przypadku całe to zaostrzenie napotyka mantrę YAGNI.

pytanie na porównywaniu OLE DB do ODBC zazwyczaj można znaleźć tutaj:

what is the difference between OLE DB and ODBC data sources?

Chociaż zadając pytania wydajności góry jest dobre pytanie nie można odpowiedzieć w kontekście aplikacji. Niestety, tylko profilowanie obu przeciwko przykładowym danym da ci odpowiedzi, których potrzebujesz.

Nie ma zbyt wiele uwagi na temat DbConnection, jest to klasa podstawowa dla innych klas połączeń specyficznych dla bazy danych.

Czy brałeś pod uwagę ORM jak NHibernate lub framework taki jak Enterprise Library Data Access Application Block? Pomogą ci one wyodrębnić bazę danych (z ORM-ami, do tego stopnia, że ​​nie musisz nawet kodować w bazie danych).

Aktualizacja: jakim mogę powiedzieć z uwag wydaje się, że jedynym rozwiązaniem jest użycie klas bazowych .NET (takich jak np DbConnection) lub interfejsy (IDbConnection). Według mojej wiedzy nie ma nic, co mogłoby dać ci poprawne połączenie dla ciągu połączenia, więc być może będziesz musiał kodować tę część. W ten sposób można zwracać OleDbConnection, OdbcConnection, SqlConnection, etc, gdy wykryje ciąg połączenia, ale używać ich w kodzie jako DbConnection lub IDbConnection, utrzymując w ten sposób kod agnostyk bazowego bazie.

Nie idealny, ale doskonale działający.

+0

Dzięki za dobrą odpowiedź. Przez programowanie na interfejsach Zakładam, że masz na myśli mądrzejszy interfejs, który jest następnie implementowany wiele razy dla każdego źródła danych? Problem polega na tym, że nie będę miał wcześniejszej wiedzy o źródle danych i otrzymam ciąg połączenia z pliku web.config (zmiany dla każdej konfiguracji skonfigurowanego użytkownika), który dyktuje źródło danych, z którym należy się połączyć. Oznacza to, że będę musiała zakodować implementację dla każdego możliwego źródła danych, które wydaje się być bardzo ciężkim przesadą, jeśli na przykład zawsze potrzebujemy 4-6 różnych platform? – CSharpened

+1

@Costrzony Musisz mieć wcześniejszą wiedzę o potencjalnych bazach danych, z którymi będzie współpracować twoja aplikacja. Jeśli nie wszystko, co możesz zrobić, to skorzystaj z najniższego wspólnego mechanizmu połączenia i ANSI SQL, więc OLE lub ODBC. Pytanie o odpowiedniość: czy wszystkie bazy danych, które musisz obsługiwać, czy oferują dostęp ODBC lub OLEDB? –

+0

Zdecydowanie nie będę posiadał wcześniejszej wiedzy, ponieważ mój kod musi być w stanie po prostu użyć dowolnego ciągu połączenia w celu nawiązania połączenia. To jest frustrujące, ale to są wymagania, które otrzymałem. Jeśli okaże się to niewykonalne, to jest w porządku, ponieważ po prostu zaprzecza koncepcji, o którą mnie poproszono. Większość źródeł danych, z których dotychczas korzystałem, obsługuje przynajmniej jeden, ale może być problem z bardziej niejasnymi.Na tym etapie poproszono mnie o wsparcie dla Oracle, PostgreSQL, SQL Server, MySQL i Spatialite plus jeden lub dwa inne. – CSharpened

3

Używanie DbProviderFactory jest dobrym wyborem, jeśli potrzebujesz agnostycznej warstwy dostępu do danych, bez kodowania dostępu do danych więcej niż jeden raz.

Nie widzę powodu, dla którego chciałbyś go ominąć, a wszystkie niezbędne funkcje są objęte klasami podstawowymi pod numerem System.Data.Common.

Używamy agnostycznego dostępu do danych pod numerem Nearforums, ponieważ dostarczamy zarówno skrypty SQL Server, jak i MySql db. O wydajności zależy to od konkretnych implementacji złącz (Oracle, MySql, PostgreSQL, ...) dostarczanych przez różne firmy/społeczności. Większość znanych złączek została właściwie przetestowana przez kilka lat.

+0

Czy masz na myśli używanie DbProviderFactory z podstawowym obiektem DbConnection? – CSharpened

+1

Dobrze, możesz zobaczyć przykład tutaj: http://davidhayden.com/blog/dave/archive/2007/10/08/CreatingDataAccessLayerUsingDbProviderFactoriesDbProviderFactory.aspx – jorgebg

+1

Dzięki za to. Dobrze to przeczytam. – CSharpened