Laden...

Forenbeiträge von PreAlpha Ingesamt 23 Beiträge

05.07.2013 - 13:07 Uhr

Wenn ich aber DataAdapter und DataSet an meine neue Form übergebe (oder eben an eine Klasse die meine Datenbankzugriffe verwaltet), wie kann ich das DataSet dann im Designer an mein Grid binden um noch vollen Designer Zugriff auf meine Grid Layout Optionen zu haben (wie z.B. Anordnung der Spalten) ?

Muss ich hierzu im Designer ein neues DataSetC erstellen, dem DataSetC den wert von DataSetB zuordnen (welches den Wert von DataSetA zugeordnet bekommen hat) um dann letztendlich DataSetB wieder den Wert von DataSetC zuzuordnen ? Das wäre dann meine bereits vermutete, wenig elegante, Methode. Das muss doch besser lösbar sein ?

LG

05.07.2013 - 11:45 Uhr

Tut mir Leid das ich jetzt das Thema nochmal rauswühlen musste.

Ich habe mein DataSet der anderen Form im Konstruktor übergeben. Das funktioniert auch wunderbar um Daten auszulesen. Wenn ich nun aber Daten in das DataSetB aus Form2 schreiben möchte, schreibt er sie zwar in das DataSetB, macht aber keine Anstalten das ganze nach einem TableAdapter.Update() in die Datenbank zu schreiben.

Nun müsste ich mein (editiertes) DataSetB aus Form2 wieder in Form1 an DataSetA übergeben und über dieses die dahinterliegende Datenbank aktualisieren. Das wird aber ziemlich unübersichtlich und wirkt zudem ziemlich unelegant (von Fehleranfälligkeit und Datensynchronität ganz zu schweigen).

Da muss es doch noch eine andere Möglichkeit geben ? Ich brauche in meiner Anwendung prinzipiell nur ein einziges DataSet aus welchem ich (und der Designer) von mehreren Forms aus zugreifen kann (meine Grids sind per Designer an das DataSet gebunden).

LG

06.06.2013 - 16:31 Uhr

Danke,

leider bringt mich das nicht so wirklich weiter.

KFormDS.Tables["Kontakte"].Rows[this.dataSourceRowHandle]["ErstelltDatum"];

wird mir nicht als Typ DateTime angegeben und somit habe ich auch keine Möglichkeit dies entsprechend zu formatieren.

06.06.2013 - 14:35 Uhr

Hallo,

ich sitze gerade daran aus einer FB Datenbank ein Date-Datenfeld auszulesen.

Der Code ist wie folgt:


this.labelControl_ErstelltDatum.Text = KFormDS.Tables["Kontakte"].Rows[this.dataSourceRowHandle]["ErstelltDatum"].ToString();

Dabei möchte ich einfach meinem Label den Datumswert zuordnen. Das klappt auch wunderbar, wäre da nicht die Tatsache das ich folgendes Format ausgegeben bekomme:

DD.MM.JJJJ HH.MM.SS

wobei die Uhrzeit auf 00:00:00 steht. Das Datum wird richtig angegeben.

Nun dachte ich, dass der Datentyp DATE bei FB im Dialect 3 wirklich nur das Datum speichert ?

Hat hier vielleicht jemand einen Rat ? Ich möchte gerne nur das Datumsformat DD.MM.JJJJ angezeigt bekommen, ohne die Uhrzeit.
Laut IBExpert ist auch nur das Datum in der Datenbank gespeichert ?!

verwendetes Datenbanksystem: Firebird 2.5

13.03.2013 - 09:51 Uhr

Hallo,

Es geht um folgendes: Ich habe eine MainForm mit einem GridView welche Daten aus einer dahinter stehenden Firebird Datenbank anzeigt (per DataSet). Nun möchte ich bei Doppelklick (bzw. Klick auf einen Button) auf eine Reihe ein neues Form zum ändern des Datensatzes öffnen (ich nenne es mal EditForm).

Nun stehe ich vor folgendem Problem: Ich muss der EditForm sagen um welchen Datensatz es sich handelt. Nun hätte ich gedacht, übergebe ich der EditForm einfach den PrimaryKey (also die ID) des gedoppelklickten Eintrages. Damit habe ich aber leider immer noch keinen Zugriff auf den kompletten Datensatz in der EditForm.

Das komplette DataSet aus dem MainForm der EditForm zu übergeben wäre wohl ein bisschen Overkill.

Gibt es da evtl. eine elegantere Lösung ? Sollte ja eigentlich nicht all zu schwer zu realisieren sein, ist es doch ein häufig anzutreffender Designansatz.

Im GridView auf der MainForm werden im übrigen nur einige Spalten der dahinter hängenden Tabelle in der Datenbank angezeigt (aus Gründen der Übersichtlichkeit). Im EditForm möchte ich allerdings auf alle Spalten des jeweiligen Records zugreifen.

LG

04.07.2012 - 15:57 Uhr

Hallo,

ich habe in meinem Programm momentan einen Kopiervorgang der Felder und Tabellen von DB1 zu DB2 kopiert und die Felder/Tabellen umbenennt.
Wenn ich nun den Kopiervorgang abbreche möchte ich den missglückten Rest der *.fdb Datei von meiner Platte löschen. Nur irgendwie hat die Firebird immernoch in Verwendung und lässt sich daher nicht entfernen.

Ich habe bereits alle mir bekannten ausgeführten Prozeduren disposed und auch schon ein System.GC.Collect() ausprobiert. Leider alles ohne Wirkung. Vllt. weis jemand wodran es liegen könnte ?

Offen hatte ich: Eine Connection, einen CMD-Builder, ein DataAdapter und ein DataSet. Alles Disposed.

LG

verwendetes Datenbanksystem: Firebird

03.07.2012 - 20:35 Uhr

Ich habe jetzt einfach eine eigene bool variable "cancelled" eingeführt welche ich beim drücken auf den Abort Button auf true setze und die Methode CancelAsync() aufrufe. In RunWorkerCompleted prüfe ich nun einfach ob cancelled true ist und werfe dann die richtige Meldung aus.

Komischerweise funktioniert das einwandfrei. Wundert mich nur einwenig, da CancelAsync() ja eigentlich e.Cancelled auf true setzen sollte.

03.07.2012 - 19:43 Uhr

Hi,

es IST ein Benutzer-Ereignis, siehe meinen früheren post weiter oben:

Naja, einfach mein Abort-Button:

  
        private void iAbbrechenButton_Click(object sender, EventArgs e)  
        {  
            backgroundWorker1.CancelAsync();  
        }  

In meiner foreach-Schleife ist noch folgendes:

  
                    if (backgroundWorker1.CancellationPending == false)  
                    {  
                        backgroundWorker1.ReportProgress((db2.Tables["Kontakte"].Rows.Count * 100) / (anzahl_db1_reihen));  
                    }  
                    else  
                    {  
                        break;  
                    }  
03.07.2012 - 18:37 Uhr

Wenn ich das richtig verstanden habe, soll ich in meine foreach-Schleife welche die Daten kopiert sowas packen:


                    if (backgroundWorker1.CancellationPending == false)
                    {
                        backgroundWorker1.ReportProgress((pro_ds.Tables["Kontakte"].Rows.Count * 100) / (anzahl_imos_reihen));
                    }
                    else
                    {
                        backgroundWorker1.CancelAsync(); // <-- Das hier
                        break;
                    }

Das funktioniert aber ebenfalls nicht. Es wird immernoch die Meldung "Done!" ausgegeben obwohl "Abbruch" erscheinen sollte.

03.07.2012 - 17:14 Uhr

In meiner DoWork steht nur folgendes:


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {


            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                Copy_db2_to_db1();
            }
        }
03.07.2012 - 16:39 Uhr

Naja, einfach mein Abort-Button:


        private void iAbbrechenButton_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }

In meiner foreach-Schleife ist noch folgendes:


                    if (backgroundWorker1.CancellationPending == false)
                    {
                        backgroundWorker1.ReportProgress((db2.Tables["Kontakte"].Rows.Count * 100) / (anzahl_db1_reihen));
                    }
                    else
                    {
                        break;
                    }
03.07.2012 - 16:20 Uhr

Hallo,

danke für die vielen Beiträge. Die Perfomance stört mich hier nicht so sehr. Das Programm wird vermutlich eh nur mal alle paar Jahre aus dem Datensalat gewühlt. Viel mehr stört mich gerade das beim canceln des backgroundworker trotzdem in die "erfolgreich erledigt" Bedingung gesprungen wird (Race).


        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("Vorgang abgebrochen!");
                unlock_textfelder();
            }
            else
            {
                MessageBox.Show("Done!");
                unlock_textfelder();
            }
        }

Die korrekte Meldung wäre mir jedoch schon wichtig. Gibt es da ein Patentrezept um soetwas zu vermeiden ?

LG

03.07.2012 - 14:31 Uhr

Mir fällt da gerade ein:

Nach der foreach-Schleife update ich die DB mit:
db2.Update(db2_ds, "Kontakte");

Ist es möglich, das die foreach-Schleife in der progressBar korrekt dargestellt wird, jedoch das Update jenes ist, welches soviel Zeit beansprucht ? Wie könnte ich dieses Updaten der DB in den progress mit einschließen ?

//Edit: habe gerade mal das update mit in die foreach schleife gepackt. So funktioniert es. Wollte zwar alles in einem Rutsch updaten, aber so habe ich wenigstens meine ProgressBar.

03.07.2012 - 14:27 Uhr

Hallo,


            backgroundWorker1.WorkerSupportsCancellation = true;
            backgroundWorker1.WorkerReportsProgress = true;
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Step = 1;

Meine ProgressPercentage geht auch von 0-100

03.07.2012 - 14:10 Uhr

Hast mal mit dem Debugger durchgesteppt, was überhaupt berechnet wird?

Ja, wenn ich durchsteppe zählt er mein e.ProgressPercentage langsam hoch.

Vorallem ob anzahl_db1_reihen gesetzt ist.

Mein anzahl_db1_reihen ist gesetzt. Das habe ich bereits überprüft.

LG

03.07.2012 - 13:51 Uhr

Hallo,

ich bin gerade dabei von einer Firebird DB (db1) zu einer anderen Firebird DB (db2) zu kopieren, da ich neue Tabellen+Feldnamen brauche.

Nun hätte ich gerne den Progress des Kopiervorgangs angezeigt. Der Kopiervorgang an sich wird vom Backgroundworker abgearbeitet.

Ich reporte den Progress in meiner Kopier-Schleife:


foreach (System.Data.DataRow db_datarow in db_ds.Tables["Inter"].Rows)
                {
                    db2_datarow["Nachname"] = db1_datarow["IName"];
                    i++;
                    backgroundWorker1.ReportProgress((i * 100) /(anzahl_db1_reihen));
                 }

Außerdem:


        private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

Nun zeigt meine Progressbar zwar etwas an, jedoch füllt sich diese innerhalb von 2-3sec obwohl der Kopiervorgang noch nicht abgeschlossen ist (dauert insgesamt momentan etwa 2-3min).

Ich weis momentan nicht so recht an was das liegen könnte. Vllt. hat von euch jemand eine Idee ?

LG

verwendetes Datenbanksystem: Firebird

13.04.2012 - 10:06 Uhr

Ich weis, meine letzte Frage passt vielleicht nicht ganz in dieses Unterforum, aber in diesem thread kann man vllt. am besten herauslesen was ich vorhabe.

Vielleicht kann mir ja jemand einen Tipp geben ohne das ich den Thread nochmal neu in einem anderen Unterforum starten muss.

LG

10.04.2012 - 15:28 Uhr

Hi, der CommandBuilder funktioniert super, danke für die Info!

Nun will ich aber den ganzen Kopiervorgangsfortschritt mit einer Progressbar anzeigen. Dazu verwende ich den BackgroundWorker.

Mein Kopiervorgang findet allerdings in der oben beschriebenen foreach Schleife in der Klasse "copyop" statt. Vor der foreach Schleife öffne ich ja meine DB Connections und schreibe die Daten in mein DataSet.

Nun habe ich das Problem, das ich meinen Backgroundworker ja von meiner MainForm aus aufrufen muss. Instanziere ich nun ein Objekt von "copyop" um dort meine copy_from_to() Funktion im Backgroundworker aufzurufen. Allerdings kann ich ja in meiner Klasse "copyop" kein Progressbericht an den Backgroundworker aus der MainForm senden ?!

Meine backgroundWorker1_doWork(), backgroundWorker1_RunWorkerCompleted() und backgroundWorker1_ProgressChanged() habe ich ebenfalls in der MainForm definiert, sowie ein Button der den Vorgang abbrechen kann.

Verhaspel ich mich vielleicht zu sehr in Kreuz- und Queraufrufe durch beide Klassen ? Momentan ist es aber aus meiner Sicht die übersichtlichste Variante alle Datenbank Kopier-Operationen in meiner Klasse copyop zu halten und per ButtonClicks aus der MainForm den backgroundWorker zu starten. Wie vollbringe ich dann aber den Spagat um dem backgroundWorker Progress an die Progressbar zu übermitteln ?!

LG

03.04.2012 - 10:06 Uhr

Lass das lieber dem Commandbuilder machen, wie schon gesagt.

Vielen Dank, ich werde mir den CommandBuilder mal anschauen!
LG

03.04.2012 - 09:20 Uhr

Hallo,

habe mich gerade wieder an das Projekt gesetzt. Mittlerweile füllt sich meine Datenbank schon mit getriggerten primary keys mit der Anzahl der zu kopierenden Rows. Leider bleiben aber die Felder, welche in die DB eingefügt werden sollen null.

Mein Code ist Momentan wie folgt:


                foreach (System.Data.DataRow datarow1 in ds1.Tables["Benutzer"].Rows)
                {
                   datarow2 = ds2.Tables["Benutzer2"].NewRow();
                   datarow2["Vorname"] = datarow1["Name"];
                   ds2.Tables["Benutzer2"].Rows.Add(datarow2);
                   da2.Update(ds2, "Benutzer2");
                }

Davor habe ich

da2.InsertCommand = "INSERT INTO Benutzer2 (Vorname) VALUES (@Name)";

gesetzt und als Parameter:

insert_cmd.Parameters.Add("@Name", FirebirdSql.Data.FirebirdClient.FbDbType.VarChar, 50);

Kann mir jemand sagen, wieso er zwar den Generator für das primary key Feld in meiner Tabelle triggert, aber keine Werte in das Feld einfügt ?

Vielen Dank und LG

29.03.2012 - 16:59 Uhr

Hallo,

mittlerweile sieht mein Quelltext deinem auch schon ziemlich ähnlich, allerdings bleibt meine Datenbank am Ende unverändert. Wie lade ich denn nun das Datenset wieder in die Datenbank ohne groß mit den DataAdapter InsertCommand-Parametern um sich werfen zu müssen ? (das wäre ja nun redundant und unnötig)


                foreach (System.Data.DataRow datarow1 in ds1.Tables["Benutzer"].Rows)
                {
                   datarow2 = ds2.Tables["Benutzer2"].NewRow();
                   datarow2["Vorname"] = datarow1["Name"];
                   ds2.Tables["Benutzer2"].Rows.Add(datarow2);
                }

Die Column "Vorname" im DataSet ds2 müsste ja nun mit den Namen aus ds1 Column "Name" gefüllt sein. Wie bekomm ich sie nun aber wieder durch den DataAdapter ohne Insert Commands in die Datenbank ? Oder geht das ohne Insert Commands garnicht ?

LG

29.03.2012 - 15:14 Uhr
  1. DataSet mit der Struktur der Datenbank öffnen. Dann Zeile für Zeile übertragen, dabei die Spalten wie gewünscht zuordnen.

Grüße Bernd

Naja, genau dadran hängts ja.


                foreach (System.Data.DataRow datarow1 in ds1.Tables["Benutzer"].Rows)
                {
                   datarow1 = ds2.Tables["Benutzer2"].NewRow();
                   datarow2["Vorname"] = datarow1["Name"];
                }
                da2.Update(ds2, "Benutzer2");

Soweit bin ich bisher.. aber die danach erstellte Datenbank ist leider unverändert. Keine Werte wurden übernommen.

Grüße

29.03.2012 - 14:15 Uhr

verwendetes Datenbanksystem: Firebird 2.5.1

Hallo,

ich versuche gerade ein, mit einer Tabelle gefülltes, DataSet in eine Datenbank zu schreiben.
Das wäre auch alles garkein Problem wenn die Columns in meiner Tabelle nicht ganz andere Namen hätten als die Columns in der Datenbanktabelle (ebenso andere Indizes). Daher fällt ein einfaches .Copy() schonmal weg.

Wie kann ich denn nun bestimmte Columns meiner Tabelle im DataSet zu bestimmten Columns meiner Datenbank (als gefilltes zweites DataSet) zuweisen und eintragen lassen ?

Oder einfacher ausgedrückt: Gibt es eine Möglichkeit die Werte aus DataSet1.Column1 explizit DataSet2.Column4 zuzuweisen ?

Ich stehe momentan echt auf dem Schlauch und wäre für jede Hilfe sehr dankbar.