Laden...

In einer Anwendung mehrere Datenbank-Typen unterstützen

Erstellt von mkolb vor 6 Jahren Letzter Beitrag vor 6 Jahren 3.431 Views
M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren
In einer Anwendung mehrere Datenbank-Typen unterstützen

Hallo,
meine Anwendung unterstützt aktuell den MS-SQL-Server, SQL-Compact und die Access-Datenbanken (MDB).
Um die Daten abzufragen, speichern, ändern, etc. habe ich relativ zentrale Routinen, aber ich verzweige immer für jede Datenbank-Technologien in eine extra Routine. So ergibt sich, daß der Code quasi 3 x vorrätig ist, allerdings an die diversen Technologien angepaßt sind.
Ich find das etwas umständlich, nicht so sauber.
Gibt es eine gute Lösung ?

Ein Ausschnitt von meinem Code in C#:

Tschau
Martin


public Boolean change(SQLDatenbank LSQLServer, FIMANMandant LMandant)
        {
            Boolean Rueckmeldung = false;
            String SQL = "Update ZAEHLER set ";
            SQL  += "NR_IMMOBILIE = @NR_IMMOBILIE,";
            ...
            SQL  += "WHERE NR = @Nr";
            switch (LSQLServer.SQLDatenbankFormat)
            {
                case DatenbankFormat.keineDatenbank_0:
                    break;
                case DatenbankFormat.SQLCompact:
                    SqlCeConnection conSqlCe = GetConnectionSqlCe(LSQLServer);
                    Rueckmeldung = change(SQL , conSqlCe, LMandant);
                    break;
                case DatenbankFormat.SQL2005Server:
                    SqlConnection conSql = GetConnectionSql(LSQLServer);
                    Rueckmeldung = change(SQL , conSql, LMandant);
                    break;
                case DatenbankFormat.Access2007:
                    OleDbConnection conOleDb = GetConnectionOleDb(LSQLServer);
                    Rueckmeldung = change(SQL , conOleDb, LMandant);
                    break;
                default:
                    break;
            }
            return Rueckmeldung;
        }
private Boolean change(String SQL, SqlConnection con)
        {
            Boolean Rueckmeldung = false;
            SqlCommand cmd = new SqlCommand(SQL, con);
            Boolean conWarClosed = false;
            try
            {
                cmd.Parameters.Add(Parameter("@NR_IMMOBILIE", SqlDbType.Int, NR_IMMOBILIE));
				...
                cmd.Parameters.Add(Parameter("@NR", SqlDbType.Int, NR));
                conWarClosed = conOpen(con);
                cmd.ExecuteNonQuery();
                Rueckmeldung = true;
            }
            catch (Exception ex)
            {
                Rueckmeldung = false;
                Debug.Print(ex.Message);
                throw;
            }
            finally
            {
                conClose(conWarClosed, con);
            }
            return Rueckmeldung;
        }	
private Boolean change(String SQL, OleDbConnection con)
        {
            Boolean Rueckmeldung = false;
            OleDbCommand cmd = new OleDbCommand(SQL, con);
            Boolean conWarClosed = false;
            try
            {
                cmd.Parameters.Add(Parameter("@NR_IMMOBILIE", OleDbType.Integer, NR_IMMOBILIE));
				..
                cmd.Parameters.Add(Parameter("@NR", OleDbType.Integer, NR));
                conWarClosed = conOpen(con);
                cmd.ExecuteNonQuery();
                Rueckmeldung = true;
            }
            catch (Exception ex)
            {
                Rueckmeldung = false;
                Debug.Print(ex.Message);
                throw;
            }
            finally
            {
                conClose(conWarClosed, con);
            }
            return Rueckmeldung;
        }		
private Boolean change(String SQL, SqlCeConnection con, FIMANMandant LMandant)
        {
            Boolean Rueckmeldung = false;
            SqlCeCommand cmd = new SqlCeCommand(SQL, con);
            Boolean conWarClosed = false;
            try
            {
                cmd.Parameters.Add(Parameter("@NR_IMMOBILIE",  NR_IMMOBILIE));
				...
                cmd.Parameters.Add(Parameter("@NR", NR));
                conWarClosed = conOpen(con);
                cmd.ExecuteNonQuery();
                Rueckmeldung = true;
            }
            catch (Exception ex)
            {
                Rueckmeldung = false;
                Debug.Print(ex.Message);
                throw;
            }
            finally
            {
                conClose(conWarClosed, con);
            }
            return Rueckmeldung;
        }		

16.834 Beiträge seit 2008
vor 6 Jahren

Arbeite mit ADO.NET und den jeweiligen gemeinsamen Basis-Klassen, zB. DbConnection, DbCommand.


DbCommand comamnd = new SqlCommand
DbCommand comamnd = new MySqlCommand
DbCommand comamnd = new OracleCommand
...

Zusammen mit ner ordentlichen Architektur - zB. Repository Pattern - dann kein Thema mehr.

PS: Access ist eine Zumutung, keine Datenbank.

F
10.010 Beiträge seit 2004
vor 6 Jahren

Um die Daten abzufragen, speichern, ändern, etc. habe ich relativ zentrale Routinen, aber ich verzweige immer für jede Datenbank-Technologien in eine extra Routine.

Das bedeutet das du nach all den Jahren in VB.NET das mit der OOP noch nicht so wirklich verstanden hast.

Ganz abgesehen von dem was Abt schon sagte ( die gemeinsamen Interfaces oder classes zu benutzen ) macht man in solchen fällen dann Klassen basierend entweder auf einem Interface oder einer Basisklasse

M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren

Das bedeutet das du nach all den Jahren in VB.NET das mit der OOP noch nicht so wirklich verstanden hast.

Sieht so eine Hilfe in einem Forum aus ?

Das meine Lösung nicht perfekt ist, ist mir klar, daher suche ich eine bessere Lösung und möchte diese auch erlernen.

3.825 Beiträge seit 2006
vor 6 Jahren

Wie Abt schon gesagt benutze die Basisklassen die für jede Datenbank funktionieren.

Du musst dann nur noch an ganz wenigen Stellen Code pro Datenbanktyp schreiben, meistens nur eine Zeile.

Bei mir sieht das z.B. so aus :

public DbConnection CreateConnection(Provider dbprovider)
{
	DbConnection conn = null;
	if (dbprovider == DatabaseProvider.SQLServerCompactEdition) conn = new SqlCeConnection();
	if (dbprovider == DatabaseProvider.MicrosoftSQLServer)
	{
		DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
		conn = factory.CreateConnection();
	}
	if (dbprovider == DatabaseProvider.MySQL) conn = new MySqlConnection();
	if (dbprovider == DatabaseProvider.MariaDB) conn = new MySqlConnection();
	if (dbprovider == DatabaseProvider.OracleSQLServer) conn = new OracleConnection();
	if (dbprovider == DatabaseProvider.OleDB) conn = new OleDbConnection();
	if (dbprovider == DatabaseProvider.PostgreSQL) conn = new SqlConnection();
	return conn;
}

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

W
955 Beiträge seit 2010
vor 6 Jahren

... wobei eine DbProviderFactory besser wäre damit es wirklich OO ist.

M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren

Hallo Bernd,
super. Scheint gut zu funktionieren.
Muß relativ wenig anpassen, aber allgemein viel weniger Code und viel übersichtlicher.
Werde es ausgiebig testen.
Danke.

Tschau
Martin

M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren

Danke, gute Hinweise. Die habe ich als Ergänzung zu Bernds Hinweise noch benötigt.

Access: ajo, schon klar.
Am Liebsten ist mir ein SQL Server, sehr schnell.
Leider steht der nicht immer zur Verfügung, daher noch SQL Compact. Ist leider recht langsam.
Access ist quasi eine Notlösung.

Tschau
Martin

J
641 Beiträge seit 2007
vor 6 Jahren
Orm Mapper

Ich würde dir den Einsatz eines Orm mappers empfehlen, da auch wenn du die interfaces verwendest, der sql code je datenbank unterschiedlich sein kann (bzw muss).

z.b. linq2db (https://github.com/linq2db/linq2db), kann alles möglichen dbs und du kannst linq zur abfrage verwenden!

cSharp Projekte : https://github.com/jogibear9988

J
641 Beiträge seit 2007
vor 6 Jahren

statt access würde ich dir sqlite empfehlen.

cSharp Projekte : https://github.com/jogibear9988

3.825 Beiträge seit 2006
vor 6 Jahren

Hallo Martin,

schau auch hier ab Kapitel 10 :

http://download.seven-c.de/files/DatenbankenHowTo.htm#10

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren

Hallo Bernd,
Deine Seite hatte ich mir gestern bereits angeschaut.
Eines war mir aufgefallen:

>> Der neue SQL Server Compact von Microsoft wurde nicht aus dem normalen SQL Server entwickelt, sondern aus dem SQL Server für Windows Mobile. Deshalb ist sein SQL-Syntax anders. Die Verwaltung der Datenbanken kann auch mit Microsoft Management Studio Express durchgeführt werden. <<

Wie kann ich mit dem MMSE mir die CompactCE-Datei anschauen ?
Ich hatte mir mal den SDF Viewer installiert, aber nur die Demo-Version.

Tschau
Martin

16.834 Beiträge seit 2008
vor 6 Jahren

Die Entwicklung von Server CE wurde bereits vor 5 Jahren eingestellt; nimm lieber die LocalDB, die den Nachfolger darstellt.
Und statt Access nimm Sqlite/LocalDB.

3.825 Beiträge seit 2006
vor 6 Jahren

Die Verwaltung der Datenbanken kann auch mit Microsoft Management Studio Express durchgeführt werden.

Das geht leider nur mit einer alten Version des SQL Management Studios. In den neueren wurde der Support wieder herausgenommen.

SQL Compact läuft immer noch recht gut, man muss nur wissen dass sie nicht weiterentwickelt wird.

Ich habe eine Testversion einer Software geschrieben, die sofort auf nahezu jedem Rechner läuft und keine Installation irgendwelcher Komponenten erfodert. Das mache ich mit dem SQL Compact. Bei SQLite und LocalDB sind Installationen von Komponenten notwendig.

Bei SQL Compact kommt nur eine Fehlermeldung wenn eine ältere Version des Compact Servers auf dem Rechner installiert ist. Dann muss man die Runtime installieren, dann reichen die DLL's nicht aus.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

M
mkolb Themenstarter:in
52 Beiträge seit 2017
vor 6 Jahren

Das geht leider nur mit einer alten Version des SQL Management Studios. In den neueren wurde der Support wieder herausgenommen.

ok, das erklärt es, daß es mit der 2014/2016er-Version nicht mehr geht. Danke.

SQL Compact läuft immer noch recht gut, man muss nur wissen dass sie nicht weiterentwickelt wird.

Ich habe leider nicht immer die Möglichkeit auf einen SQL-Server, daher setze ich nun dort SQL Compact ein. SQL-Server ist wirklich verdammt gut, sehr schnell. SQL Compact ist ca. 5-10 x langsamer, so mein Eindruck.

Habe mal nach SQLite geschaut, laut Testberichten, ist es noch langsamer als SQL Compact.

Tschau
Martin

F
10.010 Beiträge seit 2004
vor 6 Jahren

Habe mal nach SQLite geschaut, laut Testberichten, ist es noch langsamer als SQL Compact.

Wo meinst du so etwas falsches gelesen zu haben?

SQLite ist die am meisten benutzte Datenbank und wird z.b. auf Android benutzt.
Meinst du die würden die benutzen wenn die Langsam wär?
SQLite ist um längen schneller als SqlCompact.

Nur weil Bernd ( als einziger hier ) immer wieder sagt das man eine 5 Jahre eingestellte und nicht mehr gepflegte DB benutzen sollte, musst du das nicht auch tun.

@BendFfm:

Bei SQLite und LocalDB sind Installationen von Komponenten notwendig.

Was meinst du muss bei SQLite installiert werden?
Ausser der DLL, die du als verweis einbindest nichts.
Im gegenteil, DU musst bei Sql-Compact immer die 7 Nativen DLLs von Hand mit installieren.

D
985 Beiträge seit 2014
vor 6 Jahren

Die Häufigkeit der Verwendung war noch nie ein Indiz für Performance.

Auf Android/iOS wird so häufig SQlite verwendet, weil es schon eingebaut ist, es viele Beispiele für die Verwendung gibt und für die Anwendung als ausreichend performant befunden wurde und nicht weil es das Performanteste ist, was man dort kriegen kann.

Bei einer Desktop Anwendung mit einer lokalen (bzw. embedded) Datenbank würde ich allerdings auch auf SQlite setzen (wenn es für diese ausreichend performant ist). Hier zählen für mich die Punkte aktive Entwicklung, einfaches Deploy und weite Verbreitung (Fehler fallen schneller auf) mehr als nur darauf zu achten, was ist denn das Schnellste.

Wenn noch mehr Dampf gefordert wird, dann führt kein Weg an einem echten SQL-Server mit entsprechendem Sizing vorbei, denn nur ein größerer Kessel kann mehr Dampf erzeugen 😉

3.825 Beiträge seit 2006
vor 6 Jahren

Bei SQL Compact muss man 7 DLL's ins Programmverzeichnis kopieren ohne eine Installation.

Bei SQLite muss eine Redistributable C++ 2008 o.ä. installiert werden.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

2.298 Beiträge seit 2010
vor 6 Jahren

Um mal zum Einstiegsthema zurück zu kommen. Wäre es nicht tatsächlich besser, direkt die DbProviderFactories-Klasse zu verwenden? Das sollte eigentlich mit allen korrekt implementierten Datenbankprovidern funktionieren.

EDIT:
Das setzt natürlich eine Anpassung am Aufbau des Codes des TE voraus. - Der Provider sollte dabei übergeben und ausgewertet werden. - Anhand dessen liefert die Klasse ja die korrekte Connection etc.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

F
10.010 Beiträge seit 2004
vor 6 Jahren

@BendFfm:
https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
Was steht denn hier ganz groß in den ersten Sätzen auf der offiziellen Downloadseite vom SQLite DataProvider?

2.298 Beiträge seit 2010
vor 6 Jahren

Hallo,

ist jetzt nicht das Optimum was man rausholen kann, aber unter DatenbankClient ADO.NET - Providerunabhängig ist meine Datenbankclient Klasse zu finden.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |