Hallo 🙂
Ich bin grad dabei ein kleines Test-Programm zu schreiben um den Umgang mit Datenbanken zu lernen.
Um hier Datenbank-Unabhängig zu sein versuche ich gerade heraus zu finden wie man so etwas anstellen könnte.
Ich gehe hier einfach mal von 3 verschiedenen Verbindungen aus.
Mysql, SQLite und OleDB
Ein einfaches Beispiel zeigt nun das Problem:
MySqlCommand m_cmd = new MySqlCommand();
OleDbCommand o_cmd = new OleDbCommand();
SQLiteCommand s_cmd = new SQLiteCommand();
Nun habe ich ein Command, welches ich wahlweise auswählen kann.
Nur ist es nicht gerade Sinnig eben bei JEDEM Neuen Command auch dieses Spezifische Command zu Instaziieren.
Nun kann man ja Z.B. Toll Klassen ableiten.
Dies könnte ich mir z.B. so vorstellen:
private class SQLCommand : MySqlCommand {}
private class SQLCommand : OleDbCommand {}
private class SQLCommand : SQLiteCommand {}
Dies könnte ich wahlweise irgendwo am Anfang einer Datenbank-Klasse definieren.
Und dann eben statt:
MySqlCommand cmd = new MySqlCommand();
Sowas machen:
SQLcommand cmd = new SQLcommand();
Ja... Schön gedacht... Funktioniert nur nicht 😠
Um zu verstehen warum es dir Typen innerhalb einer Klasse, aber außerhalb einer Methode nicht gibt, reicht mir mein Verständnis noch nicht aus 😠
Letztendlich brauch ich einen Ansatz für eine kleine Universelle Datenbank-Klasse.
Mein Blog: http://www.frickelblog.de
Vielleicht nicht ganz passend zu deiner Frage, aber was du vorhast gibt es schon.
Schau mal nach Klassen wie DbConnection und DbCommand und was sonst noch in deren Namespace so rumlungert.
Das sieht in der tat schon recht Interessant aus.
Ich werd damit mal was Versuchen.
Danke auf jeden Fall 🙂
Mein Blog: http://www.frickelblog.de
Du könntest ein Interface erstellen, welches dann an Deine Klasse gebunden ist, dann müsstest Du nur in der jeweiligen Klasse die Datenbank spezifischen Commands und Connections referenzieren.
Dein Interface könnte zum Beispiel so aussehen:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DATA_ACCESS
{
interface IDBOperations
{
void DoOpenDataBase();
void DoQueryDataBase();
void DoCloseDataBse();
}
}
Das wäre dann für die allgemeinen Operationen die Du mit einer DB machen kannst. Danach kannst Du dieses in eine Klasse Deiner Wahl, zum Beispiel DBSql, oder DBOracle oder ähnliches implementieren und dort die jeweiligen DB spezifischen Commands, Connections etc. festlegen.
Beispielklasse DATA welches das Interface implementiert
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace DATA_ACCESS
{
class DataBase:IDBOperations
{
#region IDBOperations Member
void IDBOperations.DoOpenDataBase()
{
//Hier Dein Code
}
void IDBOperations.DoQueryDataBase()
{
//Hier Dein Code
}
void IDBOperations.DoCloseDataBse()
{
//Hier Dein Code
}
#endregion
}
}
Es gibt evenutell noch ausgeklügeltere Varianten, die eventuell von einem erfahreneren Developer als mit gepostet werden könnten. 😭
Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt
schaedld hats bereits zwar erklärt allerdings gibt es unter .NET 2 bereits die Schnittstellen dafür.
System.Data.IDataAdapter;
System.Data.IDbCommand;
System.Data.IDbConnection;
// usw..
Einfach schaedld Beispiel implementieren und die jeweiligen Schnitstellen für die Funktionen als Returns benutzen.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
mhm...
warum kann ich denn nicht einfach sowas machen:
DbCommand sql_cmdd = new DbCommand();
da bekomm ich den Fehler:
Fehler 1 Es konnte keine Instanz der abstrakten Klasse oder Schnittstelle "System.Data.Common.DbCommand" erstellt werden.
Mein Blog: http://www.frickelblog.de
warum kann ich denn nicht einfach sowas machen:
Na eben deswegen:
Fehler 1 Es konnte keine Instanz der abstrakten Klasse oder Schnittstelle "System.Data.Common.DbCommand" erstellt werden.
Weil es sich um eine abstrakte Klasse handelt. Aber Du kannst so arbeiten:
// erzeuge eine spezielle DbProvider-Klasse und daraus eine allgemeine Verbindung
OracleClientFactory newFactory = OracleClientFactory.Instance;
DbConnection connection = newFactory.CreateConnection();
// alles Weitere geht nur noch mit Db-Klassen
DbCommand cmd = connection.CreateCommand();
Die einzige spezielle Maßnahme ist die Auswahl oder Festlegung einer DbFactory-Instanz. Alles andere läuft mit den allgemeinen Db-Klassen (statt Sql, MySql, OleDb, Fb oder was auch immer; Oracle hier war nur ein Beispiel).
Nachteile: Für DbCommand.Parameters gibt es nur Add, nicht AddWithValue; aber das ist nicht viel mehr als etwas mehr Schreibarbeit. Die unterschiedlichen Dialekte bei den SQL-Befehlen müssen weiterhin beachtet werden. (Zu Lösungen in diesem Zusammenhang wirst Du mit dem Stichwort O/R-Mapper fündig.)
Gruß Jürgen
Du könntest ein Interface erstellen, welches dann an Deine Klasse gebunden ist, dann müsstest Du nur in der jeweiligen Klasse die Datenbank spezifischen Commands und Connections referenzieren.
Dein Interface könnte zum Beispiel so aussehen:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DATA_ACCESS { interface IDBOperations { void DoOpenDataBase(); void DoQueryDataBase(); void DoCloseDataBse(); } }
Das wäre dann für die allgemeinen Operationen die Du mit einer DB machen kannst. Danach kannst Du dieses in eine Klasse Deiner Wahl, zum Beispiel DBSql, oder DBOracle oder ähnliches implementieren und dort die jeweiligen DB spezifischen Commands, Connections etc. festlegen.
Beispielklasse DATA welches das Interface implementiert
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; namespace DATA_ACCESS { class DataBase:IDBOperations { #region IDBOperations Member void IDBOperations.DoOpenDataBase() { //Hier Dein Code } void IDBOperations.DoQueryDataBase() { //Hier Dein Code } void IDBOperations.DoCloseDataBse() { //Hier Dein Code } #endregion } }
Es gibt evenutell noch ausgeklügeltere Varianten, die eventuell von einem erfahreneren Developer als mit gepostet werden könnten. 😭
Hi,
Nichts zum Inhalt, aber das "Do" in den Methodennamen würde ich weglassen, ist falsches Englisch und im Deutschen würdest du doch auch nicht TuÖffneDatenbank schreiben, oder?
Gruß Thomas
Nichts zum Inhalt, aber das "Do" in den Methodennamen würde ich weglassen, ist falsches Englisch und im Deutschen würdest du doch auch nicht TuÖffneDatenbank schreiben, oder? Nicht wirklich, war ja auch nur auf die Schnelle 😉
Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt
Schau Dir mal die Beispiele von DbCommand in der MSDN an.
Da ist die Datenbankunabhängigkeit durchdacht worden. Ob es einem gefällt,
wie es gelöst wurde ist eine andere Sache, aber es funktioniert.
Hallo Sclot,
Nur ist es nicht gerade Sinnig eben bei JEDEM Neuen Command auch dieses Spezifische Command zu Instaziieren.
nein, sicher nicht. Aber das ist genau die Stunde der Erzeugungs-Entwurfsmuster. Du musst also nichts an deinen Klassen ändern und schon gar nichts selbst ableiten, sondern du musst das richtige Erzeugungs-Entwurfsmuster verwenden. Und das wäre hier wohl abstrakte Fabrik.
herbivore
Hallo Slot,
bei mir sieht es so aus :
public DbCommand CreateCommand()
{
DbCommand cmd = null;
DbProviderFactory factory;
if (Parameter.dbprovider == Parameter.DatenbankProvider.MicrosoftSQLServer)
{
factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
cmd = factory.CreateCommand();
}
if (Parameter.dbprovider == Parameter.DatenbankProvider.SQLServerCompactEdition) cmd = new SqlCeCommand();
if (Parameter.dbprovider == Parameter.DatenbankProvider.MySQL) cmd = new MySqlCommand();
if (Parameter.dbprovider == Parameter.DatenbankProvider.OracleSQLServer) cmd = new OracleCommand();
if (Parameter.dbprovider == Parameter.DatenbankProvider.OleDB) cmd = new OleDbCommand();
return cmd;
}
Die Sache mit der ProviderFactory funktioniert bei mir leider nur mit SQL-Server, aber so wie oben gehts auch.
Beachte dass die verschiedenen Datenbanken voneinander abweichende Datentypen und abweichende SQL-Syntax haben, siehe http://www.seven-c.de/files/datenbankenhowto.htm#11
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3