Laden...

Datenbankverbindungen bei Änderung des Eintrags in Combobox ändern

Erstellt von Rebbob vor 6 Jahren Letzter Beitrag vor 6 Jahren 4.037 Views
R
Rebbob Themenstarter:in
9 Beiträge seit 2017
vor 6 Jahren
Datenbankverbindungen bei Änderung des Eintrags in Combobox ändern

Hallo Community,

ich bräuchte mal etwas Hilfe.

Szenario:

Programm soll Daten in ein DataGrid schmeißen und diese Daten anschließend in eine Export Datei abspeichern.
Die Daten kommen aus verschiedenen MySQL Verbindungen, welche nicht hardcoded sein dürfen.
Jeder X beliebige der mit dem Programm arbeiten soll, muss selbstständig Datenbankverbindungen hinzufügen können.
Jeder Benutzer ist ein absoluter DAU und es muss so leicht wie möglich gehalten werden.

Die Datenbank Verbindung auch wenn sehr unsicher ( mir egal ich soll es so machen ) sollen aus einer Config.txt gelesen werden. Zudem soll das ganze nach einem bestimmten Format passieren.

[ABC]
"Server=IP;"
"Database=db_001;"
"UID=db_user_001;"
"Password=123456;"
"Gruppe=1;"
[DEF]
"Server=IP;"
"Database=db_002;"
"UID=db_user_002;"
"Password=123456;"
"Gruppe=2;"
[GHI]
"Server=IP;"
"Database=db_003;"
"UID=db_user_003;"
"Password=123456;"
"Gruppe=1;"

Die Verbindungen werden in 2 Gruppen unterteilt (1 & 2) welche so in einer ComboBox auswählbar sind.
Wenn Gruppe 1 ausgewählt ist, dann rufe alle Daten der verschiedenen Datenbanken ab und schmeiße die Daten zusammen in das DataGrid.
Das DataGrid soll auch nach einem DatePicker sortierbar sein.

Ich würde gerne wissen, welche Möglichkeiten es für solch ein Szenario gibt.
Bisher scheitere ich daran den Connection String für die jeweiligen Datenbanken aus der Config zu bekommen.

Jegliche Art von Hilfe ist erwünscht 😃

Gruß Rebbob

D
985 Beiträge seit 2014
vor 6 Jahren

Das Format dieser Config-Datei ist recht seltsam. Sieht aus wie ein kreativ (im negativen Sinne) interpretiertes Ini-Format. Wer gibt denn so etwas vor?

Da musst du dir wohl oder übel einen eigenen Parser schreiben, der das ausliest und in eine passende Struktur schreibt.

PS: Wenn ein DAU eine Gruppe auswählen soll, dann ist es für den einfacher, wenn es für die Gruppe einen aussagekräftigen Namen gibt anstatt 1 oder 2. Mit Produktion, Testbetrieb, Süddeutschland käme ich auch besser klar, obwohl ich mich nicht zu dieser Gruppe zähle.

R
Rebbob Themenstarter:in
9 Beiträge seit 2017
vor 6 Jahren

Die Gruppen haben andere Namen, welche für die DAU's absolut zufriedenstellend ist.

Wohl oder übel ein eigenen Parser schreiben klingt wohl sehr aufwendig.
Gibt es andere Möglichkeit eine Config.txt zu benutzen, mit einem Format welches nicht dem obigen entspricht?

Hinweis von Abt vor 6 Jahren

Keine Full Quotes. [Hinweis] Wie poste ich richtig?

D
985 Beiträge seit 2014
vor 6 Jahren

Als erstes würde ich es immer mit einer .config Datei (XML) versuchen, denn da gibt es entsprechende Klassen um das zu lesen und vor allem kennt sich das schon mit diesen ConnectionStrings aus und kann auch bei Bedarf diese Bereiche verschlüsseln.

Ich wäre auf jeden Fall viel zu faul, mir da was eigenes auszudenken - nur wenn es sehr gut Gründe gibt (und das entsprechende Schmerzensgeld)

Ansonsten nimmst du eben irgendwas anderes wofür du einen Deserialsierer bekommen kannst: XML, JSON, etc.

463 Beiträge seit 2009
vor 6 Jahren

Mit XML wirst du dich auf jeden Fall einfacher tun...

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

klar gibt es die - das einfachste wäre:
a) Eine klasse "Server" mit den Properties

  • Server
  • Database
  • UID
  • Password

b) Eine Klasse "ServerGroup" mit den Properties:

  • Name
  • Servers (List<Server>)

c) Eine Liste List<ServerGroup>

Das ganze serialisiert/deserialisierst du und fertig. (Siehe z.B. https://msdn.microsoft.com/de-de/library/58a18dwa(v=vs.120).aspx)

LG

W
955 Beiträge seit 2010
vor 6 Jahren

a) Eine klasse "Server" mit den Properties Das Name-Property fehlt da noch.

R
Rebbob Themenstarter:in
9 Beiträge seit 2017
vor 6 Jahren

Vielen Dank für die Zahlreichen antworten und Hilfestellungen.

Die App.config

<?xml version="1.0"?>
<configuration>
    <connectionStrings>   
        <add name="MyKey" 
             connectionString="Data Source=localhost;Initial Catalog=ABC;"
             providerName="System.Data.SqlClient"/>
    </connectionStrings>
</configuration>

Würde genau so mit einem Editor beispielweise "Notepad++" geöffnet und bearbeitet werden?
Die Leute müssten sich also an dem Format richten, welches vorgegeben wird?

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

grad die App.config-ConnectionStrings halte ich in diesem Fall für den falschen Weg, weil du hier keine eigene Struktur basteln kannst. (Speziell Gruppen etc.)

Was das Eingabeformat angeht:
Schreib die o.g. Klassen - eine entsprechende Oberfläche und lass die User besser nicht im XML rumpfuschen. Ich denke du baust für den DAU? Dann baut man eben eine hübsche Oberfläche zum Verwalten der Server mit allen nötigen Prüfungsroutinen.

LG

PS: App.config liegt zudem entweder im Verzeichnis des Programms (Admin-Rechte zum Editieren benötigt - keine gute Idee) oder wenn User-bezogen eben in einem User-Verzeichnis, was das Nutzen einer Liste für Alle unmöglich macht.

C
2.121 Beiträge seit 2010
vor 6 Jahren

Ergänzend, wenn du schon unbedingt dein eigenes Format machen willst, dann lass doch wenigstens die überflüssigen Elemente weg, nämlich Anführungszeichen um die Elemente und das ; am Ende.

D
985 Beiträge seit 2014
vor 6 Jahren

Warum möchte man an den ConnectionStrings auch was dranbasteln?

Ich würde in der Gruppe definieren, welche Verbindungen dazugehören (und eben nicht, welche Verbindung zu welcher Gruppe gehört)

BTW

Die Leute müssten sich also an dem Format richten, welches vorgegeben wird?

Ähm, ja ... immer ... egal welches Format ... wie soll man sonst die Bedeutung erkennen?

PS
Config-Dateien können liegen, wo sie wollen - nur muss man die dann explizit von der entsprechenden Stelle laden.

T
2.219 Beiträge seit 2008
vor 6 Jahren

Ich würde den Ansatz von Taipi88 verwenden.
Zusätzlich würde ich die Daten in einer Sqlite Datenbank speichern, anstelle einer txt/config Datei.
Dann kannst du direkt in der Sqlite DB die Struktur deiner Gruppen + Einträge der Gruppen in entsprechenden Tabellen speichern.

Zum Ursprungsformat:
Ini sollte schon seit Jahren nicht mehr verwendet werden.
Ebenfalls ist dieses Fanatsie Konstrukt auch kein gültiges Init Format, da die Key/Value Paare nicht als Strings in Anführungszeichen geschrieben werden.
Auf ein P/Invoke muss dann heir verzichtet werden.
Entsprechend musst du zwangsweise basteln.
Aber hier würde ich mit demjenigen sprechen, der die Vorgabe gemacht hat und nach dem wieso fragen.
Wer solche Formate noch verwendet, ist irgendwo in den 90ern hängen geblieben.
Gerade in C#/.Net nutzt man solche Format seit mehr als 10 Jahren nicht mehr bzw. seit .Net 2.0

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

R
Rebbob Themenstarter:in
9 Beiträge seit 2017
vor 6 Jahren

Ich bin mir immer noch nicht so sicher, wie ich den Benutzern ermögliche selbständig die ConnectionStrings hinzuzufügen.

Die Struktur mit den Klassen - Eigenschaften helfen mir momentan nicht bzw ich verstehe gerade nicht wofür die gebraucht werden.

Stehe gerade ziemlich auf dem Schlauch 🤔

Mein Gedankengang:

Eine GUI mit einem DataGrid sowie Buttons zum auslösen der Klassen und der Anzeige der Daten.
Eine GUI mit Feldern um Informationen zu bekommen, welche Datenbank,Server,Passwort,Benutzer und Gruppe, die in die app.config hinzugefügt werden?!

Der Query ist bei jeder Datenbank derselbe, die Leute müssen nur mit unterschiedlichen Daten arbeiten - aufgeteilt in Gruppe "Produkte" und Gruppe "Vertrieb".

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

so langsam versteh ich deinen Haken aber nicht.

Du brauchst eben noch eine GUI für das Erfassen/Bearbeiten/Löschen von Servergruppen und Servern.

Die Klassen? Die sind für mehrere Sachen nützlich:
a) Ein paar eigene Klassen würden deinem Programm sicher gut tun 😉
b) Die Klassen können im Zusammenhang mit DataBinding für die GUI genutzt werden
c) Die Klassen und die List<ServerGroup> ersparen dir durch Nutzung von Serialisierung/Deserialisierung das Schreiben eines eigenen Parsers. Da du mit Hilfe von Serialisierung aus einer List<ServerGroup> ein XML-File machen kannst - und mit Hilfe von Deserialisierung geht's dann auch umgekehrt.

LG

16.806 Beiträge seit 2008
vor 6 Jahren

Die App.Config befindet sich i.d.R. in einem Verzeichnis (Programs), auf das der normale Benutzer keine Schreibrechte hat.
Es ist also ohnehin eine andere Art und Weise zu wählen und zu empfehlen, wenn Konfigurationsänderungen erfolgen sollen und alle Benutzer die gleichen Einstellungen haben sollen.

C
2.121 Beiträge seit 2010
vor 6 Jahren

Der Query ist bei jeder Datenbank derselbe, die Leute müssen nur mit unterschiedlichen Daten arbeiten - aufgeteilt in Gruppe "Produkte" und Gruppe "Vertrieb".

Wenn ich das so lese hast du eventuell einen falschen Ansatz gewählt. Sowas nennt sich mandantenfähig. Da kann man durchaus alle Daten in einer Datenbank halten statt für jede Gruppe eine bzgl. der Struktur identische Datenbank aufzuziehen. Das ist Wahnsinn.

16.806 Beiträge seit 2008
vor 6 Jahren

Mandantenfähige Systeme haben durchaus physikalisch getrennte Datenbanken.
Je nach Systemgröße ist das auch Standard-Pattern und ein Muss, um skalierbar zu sein.

Zudem ist es bei größeren B2B Anwendungen üblich, dass Mandanten zu verschiedenen Zeitpunken mit Updates versorgt werden und nicht mit einem Big Bang alle zeitgleich.
Um das zu gewährleisten, zB. bei Änderungen der Datenbankschemen, ist eine physikalische Trennung absolut notwendig.

Hinzu kommt natürlich auch die Performance bei Abfragen von sehr großen Tabellen sowie die Sicherheitsrelevanz bei potentiellen Fehlern, weswegen eine physikalische Trennung - wenn möglich - immer zu bevorzugen ist.

Der Benutzer wählt hier aber nicht selbst seine Datenbank, sondern die Parameter, die die Anwendung als Datenquelle nimmt, ist dem System hinterlegt - oft eben nicht auf Benutzer sondern auf Gruppen- oder Mandantenebene.
Der einfachste Fall ist, dass DB Server und DB Name als Eigenschaften dem Mandantenobjekt hinterlegt sind und die Verbindung dann dynamisch im Code aufgebaut wird.

C
2.121 Beiträge seit 2010
vor 6 Jahren

Prinzipiell gebe ich dir da schon recht. Aber wenn ich die Frage so lese, Benutzer geben Datenbankdaten selbst ein, das hört sich eher nach einem sehr kleinen System an das noch seinen Weg sucht. In dieser Phase wären solche Überlegungen sehr wichtig.

R
Rebbob Themenstarter:in
9 Beiträge seit 2017
vor 6 Jahren

Ich weiß garnicht ob ich ein neues Thema aufmachen sollte, oder den hier weiterhin benutzen kann o.O

        public void TestMethode()
        {
            string FileName = "dbList.xml";
            var databases = LoadFromFile(FileName);

            MySqlConnectionStringBuilder Builder = new MySqlConnectionStringBuilder();

            Builder.UserID = databases[0].User;
            Builder.Server = databases[0].Server;
            Builder.Password = databases[0].Password;
            Builder.Database = databases[0].Database;

            using (MySqlConnection conn = new MySqlConnection(Builder.ToString()))
            {
                conn.Open();
            }
        }

Das funktioniert soweit wunderbar.

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfDatabases xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Databases>
    <User>Manfred</User>
    <Password>123456</Password>
    <Database>SecretDataBase001</Database>
    <Server>127.0.0.1</Server>
    <Group>A</Group>
  </Databases>
  <Databases>
    <User>Manfred</User>
    <Password>123456</Password>
    <Database>SecretDataBase002</Database>
    <Server>127.0.0.1</Server>
    <Group>A</Group>
  </Databases>
  <Databases>
    <User>Manfred</User>
    <Password>123456</Password>
    <Database>SecretDataBase003</Database>
    <Server>127.0.0.1</Server>
    <Group>B</Group>
  </Databases>
</ArrayOfDatabases>

Gibt es eine "leichte" Möglichkeit durch die "Databases" Blöcke zu Loopen, damit er für jeden Block einen ConnectionString baut und anschließend mit dem String eine Datenbankverbindung aufbaut und einen Query ausführt?

Ich habe keine Ahnung wie ich die "Blöcke" ansprechend könnte ohne sie expliziert mit dem Index zu packen.

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

ich muss jetzt ehrlich mal anmerken, dass dir ein Buch gut tun würde.

Du meinst sicher eine for oder foreach Schleife. Einfach googeln.

LG

Link OpenBook: http://openbook.galileocomputing.de/visual_csharp_2012/