Autor |
Beitrag |
Vegeto 
      
Beiträge: 262
|
Verfasst: Do 20.09.12 15:07
Hallo
Also ich habe jetzt mal den Code überarbeitet...
Das ist meine ClassLibary
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| namespace Projekt_DB_to_SFirmLibary { public class Zeile { public string KName { get; set; } public int Bank { get; set; } public string BName { get; set; } }
public class Zahlungen { private SqlConnection ZaConn = null; public void OpenConnection(string ZaConnStr) { ZaConn = new SqlConnection(); ZaConn.ConnectionString = ZaConnStr; ZaConn.Open(); } public void CloseConnection() { ZaConn.Close(); } public void InsertBank(Zeile rows) { string anweisung = String.Format("INSERT INTO Zahlungsfreigabe" + "(Name, Bank, BName, KNummer) Values" + "('{0}','{1}','{2}','{3}')", rows.Name, rows.Bank, rows.BName, rows.KNummer); using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn)) { cmd.ExecuteNonQuery(); } } } } |
Hier ist mein Main-Code von WinFrom:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| List<Zeile> rows = new List<Zeile>();
while (ApReader.Read()) { Zeile Zeile = new Zeile(); Zahlungen zahlungen = new Zahlungen(); zahlungen.OpenConnection(ZaConStr);
Zeile.KName = Convert.ToString(ApReader[1]); if (!ApReader.IsDBNull(2)) Zeile.Bank = Convert.ToInt32(ApReader[2]); if (!ApReader.IsDBNull(3)) Zeile.BName = Convert.ToString(ApReader[3]); if (!ApReader.IsDBNull(4)) Zeile.KNummer = Convert.ToInt32(ApReader[4]);
rows.Add(Zeile); zahlungen.InsertBank(Zeile);
zahlungen.CloseConnection(); } |
Wenn ich diesen Code Ausführe sagt er mir bei:
C#-Quelltext 1: 2: 3: 4:
| using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn)) { cmd.ExecuteNonQuery(); } |
Also die Spalte "ENummer" darf keine Null-Values haben, da es die Primary-Key Spalte ist.
Und in meiner Zeile wird diese noch nicht definiert oder gar hinzugefügt, weil ich diese Spalte/Zeile aus einer anderen Datei holen möchte.
Nun möchte ich euch fragen, ist der HauptCode soweit richtig, dass er jedesmal diese Zeilen aus der SQL-Datenbank holt und in eine andere Datenbank schreibt?
Dann wollte ich euch fragen, wie kann ich DataRelationen zwischen solchen "Verfahren" herstellen?
Mal ein beispiel:
Zitat: | Datenbank A (DB A)
ID Name Nachname
2 AA BA
5 AB BB
8 AC BC
Datenbank B (DB B)
ID Adresse Alter
1 abcstr. 22
2 abdstr. 23
3 abestr. 39
Datenbank C (DB C)
ID Name Nachname Adresse Alter
2 AA BA abcstr. 22
usw.
|
Nun Speichere ich ja die Zeile ID 2 von Datenbank A in eine Variable und gleichzeitig schreibt er diese in DB C, doch dort fehlt ja zunächst die Adresse und Alter und nun ist in einer weiteren Variable die Zeile ID 2 von DB B gespeichert. Wie schaffe ich es das beide Variablen, mit der selben ID eine GEMEINSAME Zeile bilden?
Ich hoffe ihr versteht mein Anliegen.
LG
Moderiert von Th69: Beitragsformatierung überarbeitet.
|
|
Th69
      

Beiträge: 4795
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 22.09.12 10:25
Hallo Vegeto,
ich verstehe schon dein Anliegen. Jedoch muß ich zugeben, daß es mir schwer fällt, dir kurz zu antworten, denn mir erscheint, daß du anscheinend selber immer noch nicht den Code so richtig zu verstehen scheinst.
Vom Grundaufbau ist dein Code jetzt richtig, aber es gibt noch einige kleinere Verbesserungsmöglichkeiten (die ich weiter unten aufzeige).
Nun aber ersteinmal zu deiner Hauptfrage bzgl. des Datenbank-Inserts:
es ist doch logisch, daß du erst dann die Zeile komplett in die Datenbank schreiben darfst, wenn du dir alle Daten geholt hast (insb. wenn der PrimaryKey fehlt ;-).
Also mußt du wohl vor dem Einfügen (d.h. vor dem Aufruf von InsertBank) noch die Daten aus deiner zweiten DB lesen.
Jedoch verstehe ich deinen Satz
Vegeto hat folgendes geschrieben: | ... und nun ist in einer weiteren Variable die Zeile ID 2 von DB B gespeichert. |
nicht. Hast du diese Daten nun schon vorliegen, oder weißt du, daß du sie brauchst, aber nicht wie du sie einlesen kannst? In welcher Form liegt denn deine "DB B" vor (auch als CSV-Datei)?
Laut deinem Beispiel passt die erste Zeile der DB A mit der ersten Zeile der DB B überein (obwohl die ID unterschiedlich ist). Ist dies wirklich so, oder sollen die passenden ID Zeilen zueinandergefügt werden?
Und nun noch die kleinen Verbesserungsvorschläge:
- innerhalb der Leseschleife brauchst du nicht immer wieder die Connection öffnen und schließen (packe Open und Close also außerhalb der Schleife).
- sofern du die Daten direkt in die DB schreibst, brauchst du die List<Zeile> doch gar nicht (außer du willst sie nach der Schleife noch weiterverarbeiten)
- du solltest dir einen besseren Namen als Zeile überlegen, z.B. Bankdaten o.ä.
Für diesen Beitrag haben gedankt: Vegeto
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Do 27.09.12 14:26
Zunächst einmal Danke für dein Eintrag.
Ich versuche mal deine Fragen zu beantworten.
Du hast recht, er kann sie erst dann in die DB wenn die Zeile vollständig ist, deshalb soll er auch nur GANZE Zeilen kopieen. Das habe ich auch in den vorherigen Post beschrieben.
Ohh Sorry ... da ist mir ein Fehler aufgetreten, es sollen Natürlich die selben IDs miteinander verbunden werden.
Also die einen Daten hole ich aus einer Sql-Datenbank(hier werden zwei Tabellen miteinander gejoint), die anderen Daten versuche ich Momentan aus einer Datei mit der Endung .iqy zu bekommen, hierran sitze ich momentan(weiß aber nicht wie ich das machen soll).
Ich hoffe jetzt kannst du mir vielleicht besser Helfen?
Danke für die verbesserungen, ändere ich sofort.
Lg
|
|
Th69
      

Beiträge: 4795
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 27.09.12 16:11
Hallo,
am besten, du liest deine ".iqy"-Datei am Anfang einmal in ein Dictionary<int, string[]> ein, d.h. der erste Parameter ist die Id und das String-Array deine einzelnen Spaltenwerte (am besten per String.Split).
Und dann kannst du per TryGetValue(...) die passende Id heraussuchen und auf die zugehörigen Spalten zugreifen.
Für diesen Beitrag haben gedankt: Vegeto
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Fr 28.09.12 12:32
Ohh... WoW...
Danke
Ich weiß leider nicht wie ich die ".iqy"-Datei in Visual Studio einlesen kann, habe schon so einige seiten gefunden, doch die sind auf Englisch und haben meistens immer VB.Net und nicht C#
Aber das was du da geschrieben hast sieht ya ziemlich genial aus
Werde versuchen dies einzubauen, doch dazu muss ich die Datei auslesen können... weiß aber nicht ob ich das schaffe
Danke zunächst 
|
|
Th69
      

Beiträge: 4795
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 28.09.12 12:51
Ich dachte, das ist eine normale Textdatei (wie in deinem Beispiel)?!
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Fr 28.09.12 14:48
Nein ist es nicht
Ich habe ein überschaubares Beispiel gemacht damit jeder User versteht, was ich will.
Eine ".iqy"-Datei ist eine Excel Abfrage Datei, also sie arbeitet wie Excel nur das sie halt jedesmal aktualisiert wird.
Also sie holt die Daten aus dem Internet oder Intranet.
Nur schaffe ich leider nicht eine solche ".iqy"-Datei in Visual Studio ein zubinden.
Dachte das würde mir Helfen... Hier
Doch da arbeiten die mit VB in der Excel Datei :/
Ich hoffe jmd kann mir dazu helfen, wie ich eine solche Datei in Visual Studio lesen kann mittels C#... :S
Habe es mit einem OleDb Connection versucht, bringt nichts.
Danke im Voraus.
LG
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 28.09.12 15:23
Was steht den in der iqy? Guckt da doch einfach mal mit einem Editor rein. Da steht vermutlich einfach nur'ne Url drin die man auch genauso gut direkt aufrufen kann.
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Fr 28.09.12 16:07
Ja du hast recht  mit zeichen wie = {} und so weiter...
und man kann sie einfach öffnen, es Öffnet sich eine XML-Seite, also eine Seite die wie XML aufgebaut ist, mit den einzelnen spalten.
wie kann ich den das jetzt mit Visual Studio verbinden?
einfach die URL einfügen oder wie?
Oder ein Connection String mit dieser URL?
Lg
|
|
Th69
      

Beiträge: 4795
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 28.09.12 17:09
Hallo,
mußt du die iqy-Abfrage denn zur Laufzeit deines Programms ausführen oder reicht dir einfach eine aktuelle Version der Daten. Dann lade dir doch die Daten mittels Excel und speichere sie dann z.B. als CSV-Datei (und diese kannst du dann bequem einlesen).
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Mo 01.10.12 08:15
Habe auch schon sowas überlegt, einfach im Hintergrund Excel starten lassen, dann die Daten einlesen.
Doch das Programm was ich gerade programmiere, soll später einfach im hintergrund laufen, er soll also immer die Aktuellen Datensätze von der ".iqy"-Datei holen.
Da ".iqy"-Dateien Web basierte Dateien sind, können sie mal Datensätze beinhalten, mal auch nicht.
Deswegen soll ich mit diesen Datentyp arbeiten, denn wenn jedesmal was neues Hinzugefügt wird, soll mein Programm die fehlende Zeile erweitern. Nachdem dann die Datensätze bearbeitet wurden, ist die ".iqy"-Datei wieder leer und sie wird zu einem späterem Zeitpunkt wieder befüllt.
Ich hoffe ihr versteht was ich meine.
Doch ich überlege gerade er kann das ya auch so machen wie du es mir vorgeschlagen hast, dass heißt er soll jedesmal eine .csv datei erstellen... Doch ich überlege gerade das werden später unviele(sehr viele) .csv datei.
Und man soll das ja nicht alles per Hand als .csv datei speichern...
hmm... irgendwie weiß ich nicht mehr weiter :S
Lg
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Mo 01.10.12 12:04
Also Ich habe mal eine neue Idee
Also ich dachte mir ich starte mittels C# Excel und lasse dann die Datei öffnen
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| Excel.Application excel = new Excel.Application(); excel.Visible = true;
string appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string filename = Path.Combine(appPath, @"teeest.iqy");
Excel.Workbook workbook = excel.Workbooks.Open(filename); Excel.Worksheet worksheet = workbook.Worksheets[1]; |
habe das so gemacht
Nur weiß ich jetzt nicht wie ich diese Werte/Datensätze ansprechen soll und wie bei der SQL-Abfrage meine Zeilen in Variablen speichern :/
Lg
|
|
Vegeto 
      
Beiträge: 262
|
Verfasst: Mo 01.10.12 15:44
So habe nun weiter gearbeitet
Aber irgendwie geht das nciht wie ich das will :/
Hier mal mein Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| Excel.Application excel = new Excel.Application(); Excel.Range range = null; excel.Visible = false; string appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string filename = Path.Combine(appPath, @"teeest.iqy");
Excel.Workbook workbook = excel.Workbooks.Open(filename); Excel.Worksheet worksheet = workbook.Worksheets[1];
range = worksheet.UsedRange; int rowCount = 0;
List<Zeile> rows = new List<Zeile>();
Zahlungen zahlungen = new Zahlungen(); zahlungen.OpenConnection(ZaConStr);
for (rowCount = 1; rowCount <= range.Rows.Count; rowCount++) { if ((range.Cells[rowCount, 1] as Excel.Range).Value2 != null) { try { Zeile RechnungsDaten = new Zeile();
RechnungsDaten.Betrag = (Int32)(range.Cells[rowCount, 0] as Excel.Range).Value2; RechnungsDaten.Verwendung1 = (string)(range.Cells[rowCount, 1] as Excel.Range).Value2; RechnungsDaten.Verwendungs2 = (string)(range.Cells[rowCount, 2] as Excel.Range).Value2; RechnungsDaten.Fä = (Int32)(range.Cells[rowCount, 3] as Excel.Range).Value2; RechnungsDaten.Fr = (string)(range.Cells[rowCount, 4] as Excel.Range).Value2; RechnungsDaten.Bemerk = (string)(range.Cells[rowCount, 5] as Excel.Range).Value2; RechnungsDaten.Bdatum = (DateTime)(range.Cells[rowCount, 6] as Excel.Range).Value2; RechnungsDaten.Zart = (string)(range.Cells[rowCount, 7] as Excel.Range).Value2; RechnungsDaten.ZV = (Boolean)(range.Cells[rowCount, 8] as Excel.Range).Value2; RechnungsDaten.Etyp = (string)(range.Cells[rowCount, 9] as Excel.Range).Value2; RechnungsDaten.Pfad = (string)(range.Cells[rowCount, 10] as Excel.Range).Value2; RechnungsDaten.Belegn = (Int32)(range.Cells[rowCount, 11] as Excel.Range).Value2; RechnungsDaten.Kundenn = (Int32)(range.Cells[rowCount, 12] as Excel.Range).Value2; RechnungsDaten.DID = (Int32)(range.Cells[rowCount, 13] as Excel.Range).Value2; RechnungsDaten.ERP = (Int32)(range.Cells[rowCount, 14] as Excel.Range).Value2;
rows.Add(RechnungsDaten); zahlungen.InsertRechnung(RechnungsDaten); } catch { } } } zahlungen.CloseConnection(); |
habe das so gemacht wie oben schon einmal gemacht.
C#-Quelltext 1:
| range.Cells[rowCount, 0] as Excel.Range).Value2; |
habe ich von einer Internet seite  Ich weiß aufjedenfall das die zweite zahl die Spalte angibt.
Und das davor und danach habe ich einfach übernommen, doch irgendwie kopiert er garnichts, weder Fehlermeldung noch irgendwas...
Kann mir jemand helfen?
Lg
PS.:
Hilfsklasse:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public void InsertRechnung(Zeile rows) { string anweisung = String.Format("INSERT INTO Zahlungsfreigabe" + "(Betrag,Verwendung1,Verwendung2,Fä,Fr,Bemerk,Bdatum,Zart,ZV,Etyp,Pfad,Belegn,Kundenn,DID,ERP) Values" + "('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}')", rows.Betrag, rows.Verwendung1, rows.Verwendung2, rows.Fä, rows.Fr, rows.Bemerk, rows.Bdatum, rows.Zart, rows.ZV, rows.Etyp, rows.Pfad, rows.Belegn, rows.Kundenn, rows.DID, rows.ERP); using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn)) { cmd.ExecuteNonQuery(); } } |
Danke schonmal fürs lesen 
|
|
|