Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - Zeile in Variable speichern mittels DataReader


Vegeto - Do 13.09.12 13:59
Titel: Zeile in Variable speichern mittels DataReader
Hallo, habe nun dieses Thema geöffnet, weil es in dem anderen thema eine falsche überschrift hatte.(Tipp von TH69)

Okay... Also habe nun lange DataReader Objekt gelesen.
Doch ich schaffe es einfach nicht :/

Also ich möchte aus einer Tabelle(aus der DB, wird aus zwei Tabellen zusammen gejoint/leftjoin, mit NULL-Werten), jetzt möchte ich jede Zeile in eine Variable stecken. Doch einige Zeilen haben Zellen, die noch nicht gefüllt sind.

Jetzt habe ich das so gemacht:

C#-Quelltext
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:
        private void holen_btn_Click(object sender, EventArgs e)
        {
            SqlConnection Conn = new SqlConnection(conStr);
            Conn.Open();
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = SelectStr; 
            cmd.Connection = Conn;

            SqlDataReader dr = cmd.ExecuteReader(); 
                                  
            while (dr.Read())
            {
                int AN = dr.GetInt32(0);
                string Name = dr.GetString(1);
                //diese drei spalten haben viele Null-Values, weil sie noch nicht gefüllt wurden, doch eine Zeile hat in jeder Zeile was stehen.
                int Bank = dr.GetInt32(2);
                string BName = dr.GetString(3);
                int KNummer = dr.GetInt32(4);  

                string Ausgabetext = String.Format("{0},{1},{2}.{3},{4}",AN,Name,Bank,BName,KNummer);
                MessageBox.Show(Ausgabetext, "Korrekt");
            }            
            
            dr.Close();
            Conn.Close();
        }


Der Fehler kommt hier:

C#-Quelltext
1:
int AdressNummer = dr.GetInt32(0);   //Die angegebene Umwandlung ist ungültig.                    


Ich weiß aber nicht woran das liegt, denn die erste Spalte besteht ausschließlich nur aus INT werten.

Ich weiß eigentlich will ich die ganze Zeile in EINE variable(vllt. List-Objekt) aber zunächst einmal will ich dieses Problem schaffen, denn ich denke es wird mir später weiter helfen.

LG


Ralf Jansen - Do 13.09.12 14:04

Der Wert ist entweder gar kein Int32 oder NULL. In beiden Fällen wird dein Code knallen. Der DataReader hat für letzteren Fall eine IsDBNull Funktion mit der du das testen kannst. Im anderen Fall solltest du dein Spaltendefinition checken ob du den die Spalte im SQL Server auch als Integer angelegt hast.


Vegeto - Do 13.09.12 14:23

Also Null ist es nicht.

habe mal eben in die Datenbank geguckt und du hast recht, er hat den Wert nvarchar(10).

Habe sofort den Code geändert in:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
while (dr.Read())
            {
                int AN = Convert.ToInt32(dr[0]);
                string Name = Convert.ToString(dr[1]);
                //Diese drei spalten haben null values, habe bei Bankleitzahl versucht die Null Values zu bearbeiten doch dann kommen zwei fehler.
                //int Bank = Convert.ToInt32(dr[2]);
                string BName = Convert.ToString(dr[3]);
                int KNummer = Convert.ToInt32(dr[4]);
                if (!dr.IsDBNull(2))               
                    int BankLeitzahl = Convert.ToInt32(dr[2]);  // hier sagt er: Eine eingebettete Anweisung kann keine Deklaration und keine Anweisung mit Bezeichnung sein.                 

                string Ausgabetext = String.Format("{0},{1},{2},{3},{4}",AN,Name,Bank,BName,KNummer); // hier sagt er: Verwendung der nicht zugewiesenen lokalen Variablen "BankLeitzahl"

                MessageBox.Show(Ausgabetext, "Korrekt");
            }


Es tauchen diese beiden fehler auf :/
habe auch versucht die if anweisung in klammern ( { } ) zu setzen, funktoniert auch nicht, habe versucht

C#-Quelltext
1:
2:
3:
int Bank; 
if(!dr.IsDBNull(2))
Bank = Convert.ToInt32(dr[2]);  // Verwendung der nicht zugewiesenen lokalen Variablen "BankLeitzahl"...genau wie oben


hat auch nichts gebracht :/

LG

Dankesehr


Ralf Jansen - Do 13.09.12 14:38

Du must Bankleitzahl mit irgendwas initialisieren da ein int nicht null sein kann. Da du Bankleitzahl aber nur in dem Zweig des If setzt gibt es wege bis zur Verwendung von Bankleitzahl in dem nie ein Wert Bankleitzahl zugewiesen wird. Das darf nicht sein. Variablen müssen immer einen zugewiesen Wert haben bevor sie verwendet werden können.

Denk dir also eine Wert aus der in Bankleitzahl stehen soll wenn der Wert in der Datenbank dafür null wäre. Alternativ nimm einen Nullable int (also int?). Dann bist du aber im folgenden bei der Verwendung dieser Variablen immer gezwungen zu prüfen ob der nicht auch null ist. Ähnlich wie jetzt schon beim DataReader.


Vegeto - Do 13.09.12 15:07

Verstehe..

habe das demnach so gelöst:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
            while (dr.Read())
            {
                int AN = Convert.ToInt32(dr[0]);
                string Name = Convert.ToString(dr[1]);
                int Bank = 0;
                string BName = "";
                int KNummer = 0;

                if (!dr.IsDBNull(2))               
                     Bank = Convert.ToInt32(dr[2]);               
                if (!dr.IsDBNull(3))
                    BName = Convert.ToString(dr[3]);             
                if (!dr.IsDBNull(4))
                    KNummer = Convert.ToInt32(dr[4]);
                 

                string Ausgabetext = String.Format("{0},{1},{2},{3},{4}",AN,Name,Bank,BName,KNummer);
                MessageBox.Show(Ausgabetext, "Korrekt");
            }

So zeigt er in der MessageBox, das was ich will nur halt die Null-Values ersetzt er mit 0, aber die habe ich ja zugewiesen. Das mit int? habe ich nicht hinbekommen :/ aber auch wenn sie sie mit If Abfange zeigt er ja irgendwo ja null an, denn wenn dort ein Null-Value vorhanden ist mit ich ihn ja mit IF ersetzen.

Okay Kommen wir zu part 2 (:
Jetzt will ich die ganze zeile in ein List-Objekt stecken oder ist ein Array besser dafür geeignet ? ? ?(Also ich würde sagen das einzelnen Variablen besser geeignet sind oder ? ?)
Denn ich möchte dieses Verfahren auf zwei typen benutzen, eine ist eine Tabelle und die andere eine Excel Datei, jz möchte ich die Werte in eine Variable packen und später in eine neue Datenbank in eine Zeile zusammen führen lassen.


Hoffe versteht was ich meine (:

LG


Ralf Jansen - Do 13.09.12 15:29

Schreibe dir eine Klasse mit deinen bisherigen Variablen als Properties. In deiner DataReader.Read Schleife erzeugst du eben dann diese Klasse weißt die Werte den Properties zu anstatt den Variablen und packst die Klasse dann in eine Liste. Also z.B. eine List<DeineNochAuszudenkendeKlasse>.


Vegeto - Do 13.09.12 15:41

Hmm...

So in etwa?

C#-Quelltext
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:
//Die Klasse
    public class Zeile
    {
        public int AN { get; set; }
        public string Name { get; set; }
        public int Bank { get; set; }
        public string BName { get; set; }
        public int KNummer { get; set; }
    }

//Klasse wird instanziert
Zeile Zeilen = new Zeile();

        private void holen_btn_Click(object sender, EventArgs e)
        {
            //...Code

            SqlDataReader dr = cmd.ExecuteReader();
                         
            while (dr.Read())
            {
                Zeilen.AN = Convert.ToInt32(dr[0]);
                Zeilen.Name = Convert.ToString(dr[1]);
                Zeilen.Bank = Convert.ToInt32(dr[2]);
                Zeilen.BName = Convert.ToString(dr[3]);
                Zeilen.KNummer = Convert.ToInt32(dr[4]);

            } 
            List<Zeile> zeilen = new List<Zeile>();
          }

Ist das so richtig, ich weiß nciht ob ich überprüfen kann ob die Zeilen so neben einander stehen?

Lg


Ralf Jansen - Do 13.09.12 15:44

Klasse erzeugen gehört mit in die Schleife. Genauso wie das hinzufügen zu Liste.
Damit ist dann auch klar das du die Liste vorher erzeugen mußt und nicht nachher.


Zitat:
Ist das so richtig, ich weiß nciht ob ich überprüfen kann ob die Zeilen so neben einander stehen?


Was heißt das? Die Daten sind in der Liste erstmal in der Reihenfolge in der du die sie hinzugefügt hast. Wenn du die zu irgendeinem Zeitpunkt in einer bestimmten Reihenfolge brauchst solltest du die dann sortieren.


Vegeto - Do 13.09.12 15:54

Jetzt komme ich garnicht mehr mit :/

habe nun dies getan:

C#-Quelltext
1:
2:
3:
4:
5:
 while (dr.Read())
            {
                List<Zeile> Zeilen = new List<Zeile>();
                Zeilen.Add(dr["AN"];  //Fehler:Die beste Übereinstimmung für die überladene System.Collections.Generic.List<ClassLibrary1.Zeile>.Add(ClassLibrary1.Zeile)-Methode hat einige ungültige Argumente.
            }

Komisch...Hätte nie gedacht das es so schwierig wird :/
Danke bis hierhin.

Was muss ich den nun tun? Und was meinst du mit sortieren, sie sind doch schon in der Klasse sortiert, bekomme ich keine Zeile in dieser Reihnfolge?

LG


Ralf Jansen - Do 13.09.12 16:02


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
List<Zeile> zeilen = new List<Zeile>();
while (dr.Read())
{
   Zeile zeile = new Zeile();
   // hier jetzt Daten in zeile einfügen
   zeilen.Add(zeile);
}


Zitat:
Und was meinst du mit sortieren, sie sind doch schon in der Klasse sortiert, bekomme ich keine Zeile in dieser Reihnfolge?


Die Daten sind in der Liste genau in der Reihenfolge wie du sie aus der DB holst. Also wenn du einen Order By in deinem SQL hast dann genau so. Sonst so wie die Datenbank das dann zufällig liefert.
Und wenn du sie später irgendwo anders sortiert brauchst dann mußt du halt die zeilen Liste sortieren.

Wenn dich das verwirrt ignorier das erstmal. Du hattest was von Zeilen ~nebeneinander~ geschrieben. Und natürlich haben die Zeilen irgend eine Reihenfolge solange du aber nirgendwo eine eindeutig definierst dann ist die halt potentiell zufällig.


Vegeto - Do 13.09.12 16:18

Ahhh Dankeschön :D :D
(Danke habe bis hierhin eine menge gelernt :), bin in der nächsten woche in der berufschule, hoffe das ich dort genau so viel lerne :) nebenbei werde ich auch in sämtlichen foren und büchern lesen :))

So:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
            List<Zeile> zeilen = new List<Zeile>();
            while (dr.Read())
            {
                Zeile Zeilen = new Zeile();
                Zeilen.AN = Convert.ToInt32(dr[0]);
                Zeilen.Name = Convert.ToString(dr[1]);
                Zeilen.Bank = Convert.ToInt32(dr[2]);  //Fehler: Ein Objekt kann nicht von DBNull in andere Typen umgewandelt werden.
                Zeilen.BName = Convert.ToString(dr[3]);
                Zeilen.KNummer = Convert.ToInt32(dr[4]);
                row.Add(Zeilen);
            } 
            

            dataGridView1.DataSource = zeilen.ToList();


Doch nun muss ich irgendwie die Null-Values bearbeiten, habe ein try-Catch-Block drum herum gemacht, doch hat auch nichts gebracht, dann zeigt er dauerhaft den Fehler an: "Ein Objekt kann nicht von DBNull in andere Typen umgewandelt werden."

ich möchte das er durchgeht und wenn NULL-values vorhanden sind, soll er eine Meldung geben, es fehlen Daten, doch trotzdem soll er die Zeile anzeigen die keine Null-Value haben.

Wie kann ich das festhalten, wieder mit einer if-anweisung?

Lg


Ralf Jansen - Do 13.09.12 16:23

.. und dem bekannten Test mit IfDBNull.


Vegeto - Do 13.09.12 16:26

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
.. und dem bekannten Test mit IfDBNull.


Weiß leider nicht wie ich diesen Aufbauen soll.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
if(DBNull..//weiß nicht mehr weiter :/
while (dr.Read())
            {
                Zeile Zeilen = new Zeile();
                Zeilen.AN = Convert.ToInt32(dr[0]);
                Zeilen.Name = Convert.ToString(dr[1]);
                Zeilen.Bank = Convert.ToInt32(dr[2]);
                Zeilen.BName = Convert.ToString(dr[3]);
                Zeilen.KNummer = Convert.ToInt32(dr[4]);
                row.Add(Zeilen);
            }


gibts du mir ein TPP :)

Lg


Ralf Jansen - Do 13.09.12 16:28

Du hast es bei direkten Variablen doch auch hinbekommen? Das ist jetzt nicht anders.


Vegeto - Do 13.09.12 16:31

Also muss ich das auch für jeden Zeile einzelnen machen, ich kann nicht einfach vor die While Schleife ein If setzen und der soll dann alle Zeilen überprüfen?

Edit:
SO?

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
while (dr.Read())
            {
                Zeile Zeilen = new Zeile();
                
                Zeilen.AN = Convert.ToInt32(dr[0]);
                Zeilen.Name = Convert.ToString(dr[1]);
                if(!dr.IsDBNull(2))
                Zeilen.Bank = Convert.ToInt32(dr[2]);
                if (!dr.IsDBNull(3))
                Zeilen.BName = Convert.ToString(dr[3]);
                if (!dr.IsDBNull(4))
                Zeilen.KNummer = Convert.ToInt32(dr[4]);
                row.Add(Zeilen);
            } 
            
            dr.Close();
            ApConn.Close();
            dataGridView1.DataSource = row.ToList();


So zeigt er aber jede zeile an und ersetzt die Null-values mit Null oder Leer String...
Doch er soll dann nur die vollständige zeile anzeigen?

Lg


Ralf Jansen - Do 13.09.12 16:37

Natürlich. Wenn dein if um alles fehlschlägt wurde ja gar keine Property gesetzt und nicht nur die die nicht zuweisbar (weil null) sind. Das würde nur Sinn machen wenn du gar keine Zeile anlegen willst wenn eine der Properties der Zeile nicht ok wären.


Vegeto - Do 13.09.12 17:07

Okay Dankeschön...

Danke bis hierhin habe sehr viel gelernt und geschafft, bin gerade zuhause angekommen, werde morgen ein feedback mit meinem arbeitskoleggen halten.. melde mich dann bei euch...

DANKE an alle...

Lg


Vegeto - Fr 14.09.12 09:26

Guten Morgen..

Ich bräuchte mal wieder euere Hle (:

Mein Code:

C#-Quelltext
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:
            List<Zeile> row = new List<Zeile>();
            
            while (dr.Read())
            {
                Zeile Zeilen = new Zeile();               
                
                Zeilen.KName = Convert.ToString(dr[1]);
                if(!dr.IsDBNull(2))
                Zeilen.Bank = Convert.ToInt32(dr[2]);
                if (!dr.IsDBNull(3))
                Zeilen.BName = Convert.ToString(dr[3]);
                if (!dr.IsDBNull(4))
                Zeilen.KNummer = Convert.ToInt32(dr[4]);

                row.Add(Zeilen);


            }            
            dr.Close();
            ApConn.Close();


// das ist der Code von meiner ClassLibary, zum hinzufügen der datensätze in DB
public void InsertBank(Zeile row)
        {
            string anweisung = String.Format("INSERT INTO Zahlung" + 
                "(KName, Bank, BName, KNummer) Values" + 
                "('{0}','{1}','{2}','{3}')", row.KName ,row.Bank, row.BName, row.KNummer);

            using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn))
            {
                cmd.ExecuteNonQuery();
            }

        }


Doch irgendwie bekomme ich das nicht hin das er die einfügt.

Habe auch das hier probiert:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Zeile Zeilen = new Zeile {KName = Convert.ToString(dr[1]),
                if(!dr.IsDBNull(2))
                Zeilen.Bank = Convert.ToInt32(dr[2]),
                if (!dr.IsDBNull(3))
                Zeilen.BName = Convert.ToString(dr[3]),
                if (!dr.IsDBNull(4))
                Zeilen.KNummer = Convert.ToInt32(dr[4])};

zahlung.Insert(Zeilen); //Methode aus meiner ClassLibary... Doch funktoniert nicht da kein IF benutzt werden darf.

Doch hier darf ich kein if verwenden :/

Weiß jmd bescheid, wie ich den inhalt von List wieder geben kann?
Dachte es würde mit List[1] <--- für den ersten punkt der liste funktionieren, doch es funktioniert nicht :(

Das problem ist ja, dachte mir dann ich stecke sie in einzelnen Variablen, doch die Variablen sind auch nur in der While-Schleife vorhanden, kann sie ja ausserhalb nicht ansprechen.

Lg


Ralf Jansen - Fr 14.09.12 15:23

Du sprichst(fragst) in rätseln.
Dort wo du im ersten Code row.Add aufrufst kannst du stattdessen oder zusätzlich dein zahlung.Insert aufrufen. Da hast du ja ein korrektes Zeile Objekte(mit Namen Zeilen). Wenn du es an anderer Stelle brauchst dann sag wo und wie das mit dem anderen Code zusammenhängt.


Achte bei deinen Verwendung von Bezeichner auf die richtige Verwendung von Singular und Plural. Und einheitliche Groß/Kleinschreibung wäre auch nett (Variablen klein, Methoden und Typen groß).

List<Zeile> row - da gehts um eine Liste enthält also mehrere Objekte da wäre der Plural angebracht
Zeile Zeilen = new Zeile(); - hier wiederum geht um ein einzelnes Objekt also sollte der Bezeichner auch im Singular geschrieben werden.

Wenn du das wie hier durcheinander wirfst bringst du dich nur selbst (und natürlich andere die deinen Code lesen oder damit arbeiten müssen) durcheinander.


Vegeto - Mi 19.09.12 12:52

Danke sehr...

ich habe das projekt momentan nicht bei mir, bin in der Berufssschule.

Werde das sofort ausprobieren, wenn ich die gelegenheit habe.

Ich soll also die Bezeichner ändern, damit die Kunden/Leute eine überschaubaren Code bekommen.

Aber du hast verstand was ich erreichen will oder?

Lg


Vegeto - Do 20.09.12 15:07

Hallo :)

Also ich habe jetzt mal den Code überarbeitet...
Das ist meine ClassLibary :)

C#-Quelltext
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
    {
        //hier sind die Spalten drinne z.B:
        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(); // Der Wert NULL kann in die 'ERP Nummer'-Spalte, 'Zahlungen.dbo.Zahlungsfreigabe'-Tabelle nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei INSERT. Die Anweisung wurde beendet.
}

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 user profile iconTh69: Beitragsformatierung überarbeitet.


Th69 - 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.ä.


Vegeto - 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 - Do 27.09.12 16:11

Hallo,

am besten, du liest deine ".iqy"-Datei am Anfang einmal in ein Dictionary<intstring[]> 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.


Vegeto - 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 - Fr 28.09.12 12:51

Ich dachte, das ist eine normale Textdatei (wie in deinem Beispiel)?!


Vegeto - 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 [http://blogs.office.com/b/microsoft-excel/archive/2009/07/31/using-parameters-with-web-queries.aspx]

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 - 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 - 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 - 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 - 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 - Mo 01.10.12 12:04

Also Ich habe mal eine neue Idee :D :D :D

Also ich dachte mir ich starte mittels C# Excel und lasse dann die Datei öffnen :D

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 - Mo 01.10.12 15:44

So habe nun weiter gearbeitet :)

Aber irgendwie geht das nciht wie ich das will :/
Hier mal mein Code:

C#-Quelltext
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// wenn ich das hier auf true setze öffnet sich Excel, mehr aber nicht!

            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++)
            {
                //Hier haben wir Zugriff auf jede Zeile
                if ((range.Cells[rowCount, 1as Excel.Range).Value2 != null)
                {
                    try
                    {
                        Zeile RechnungsDaten = new Zeile();                       

                        RechnungsDaten.Betrag = (Int32)(range.Cells[rowCount, 0as Excel.Range).Value2;
                        RechnungsDaten.Verwendung1 = (string)(range.Cells[rowCount, 1as Excel.Range).Value2;
                        RechnungsDaten.Verwendungs2 = (string)(range.Cells[rowCount, 2as Excel.Range).Value2;
                        RechnungsDaten.Fä = (Int32)(range.Cells[rowCount, 3as Excel.Range).Value2;
                        RechnungsDaten.Fr = (string)(range.Cells[rowCount, 4as Excel.Range).Value2;
                        RechnungsDaten.Bemerk = (string)(range.Cells[rowCount, 5as Excel.Range).Value2;
                        RechnungsDaten.Bdatum = (DateTime)(range.Cells[rowCount, 6as Excel.Range).Value2;
                        RechnungsDaten.Zart = (string)(range.Cells[rowCount, 7as Excel.Range).Value2;
                        RechnungsDaten.ZV = (Boolean)(range.Cells[rowCount, 8as Excel.Range).Value2;
                        RechnungsDaten.Etyp = (string)(range.Cells[rowCount, 9as Excel.Range).Value2;
                        RechnungsDaten.Pfad = (string)(range.Cells[rowCount, 10as Excel.Range).Value2;
                        RechnungsDaten.Belegn = (Int32)(range.Cells[rowCount, 11as Excel.Range).Value2;
                        RechnungsDaten.Kundenn = (Int32)(range.Cells[rowCount, 12as Excel.Range).Value2;
                        RechnungsDaten.DID = (Int32)(range.Cells[rowCount, 13as Excel.Range).Value2;
                        RechnungsDaten.ERP = (Int32)(range.Cells[rowCount, 14as 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, 0as 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 :)