none
Veränderte Daten aus DataGrid filtern und in Datenbank speichern RRS feed

  • Frage

  • Hallo, ich stehe gerade vor einem Problem. Ich schildere einmal.

    Ich lese drei DB-Tabellen in ein DataSet ein. Diese Tabellen verknüpfe ich im DataSet (Tabelle1 mit Tabelle2, Tabelle1 mit Tabelle3) mit DataRelations. Der Hintergrund: Alle drei Tabellen werden dann an eine DataView gelegt, und diese dann in einem DataGrid visualisiert. Jetzt hat der User alle Daten die er braucht im DataGrid. Nun kann er Daten in den Spalten der Tabelle3 eingeben. Dann müssen die geänderten Daten über einen Cick auf einen Button gespeichert werden (alle veränderten Daten der Tabelle3). Nun, ich hatte schon verschiedene Ansätze versucht:

    • DataTable des DataSets auf DataRowState untersucht ==> hatte aber keine Änderungen angezeigt bekommen
    • Alle Datensätze ( DataGrid.Items in DataRowView gewandelt) durchlaufen und auf IsEdit / IsNew / RowVErsion abgeklappert ==> keine Änderung sichtbar

    Wie mache ich das nun am einfachsten, die DataRow die verändert wurde zu greifen, damit ich die in die Datenbank zurückschreiben kann?

    Hat einer einen guten Ansatz? Das mit den verknüpften Tabellen sehe ich als Vorteil, da ich so nur die nötigen Daten in separaten Tabellen speichern kann und keine gesamte Tabelle ertsellen muss.

    Dienstag, 8. Mai 2012 06:55

Alle Antworten

  • Wenn die Daten richtig gebunden sind, wird bei Änderungen der RowState so geändert, dass der DataAdapter beim Update erkennt, was zu machen ist. Nur die betreffenden Datensätze werden aktualisiert. Falls Du vorher mit den Datensätzen etwas machen willst, kannst Du Dir diese mit Select und der entsprechenden Überladung zurückgeben lassen.
     
    --
    Viele Gruesse
    Peter
    Dienstag, 8. Mai 2012 07:34
  • Ja Peter, danke für die Info. IC suche auch schon danach die Spalten die wirklich für das "Speichern" berücksichtigt werden sollen zu binden.

    Bin ich da richtig? Ich durchlaufe nach dem zuweisen der Daten an das DataGrid ineiner SChleife die Spalten, und binde dise über Binding an die betreffende Tabelle?

    Dienstag, 8. Mai 2012 07:46
  • Ich verstehe Deine Herangehensweise bzw. Frage nicht.
     
    Üblicherweise wird in der Anwendung ein Datenpuffer erstellt und mit Daten gefüllt, die dem abzubildenden horizontalen Prozess entsprechen. Dieser Datenpuffer kann strukturell und inhaltlich der externen Datenbank entsprechen. Das ist aber nur ein Sonderfall. Üblicherweise werden in den Datenpuffer nur einige Datensätze und auch nicht alle Spalten und alle Tabellen der externen Datenbank geladen.
     
    Alle diese Daten werden komplex an die Oberfläche gebunden, d.h. sie sind alle in der Oberfläche vorhanden. Ggf. wird über ein Filter- und Sortierkriterium der für die Anzeige genutzten Sicht die Anzeige angepasst (eingeschränkt, veränderte Reihenfolge). Es besteht keine Notwendigkeit, einzelne Datensätze zu binden. Binden kann man den aktuellen Datensatz einer Datenquelle für die Bearbeiten in einer Detailsicht.
     
    Mit der Speichern-Funktion wird Edit-Vorgang beendet und der gesamte Datenpuffer in die Datenbank geschafft. Über die RowStates bei Nutzung von DataSets werden aber nur die Datensätze wirklich aktualisiert, die im Client geändert wurden.
     
    Bei einer derartigen Herangehensweise ist das Durchlaufen von Schleifen nicht erforderlich.
     
    --
    Viele Gruesse
    Peter
    Dienstag, 8. Mai 2012 08:12
  • Ja was heißt das nun für mich? Drei Tabellen sind an eine DataView gebunden, die DataView wiederum an das DataGrid.

    Das heißt dann wenn Änderungen in Zellen vornehme, gehen diese durdch, warten aber nich auf das endgültige Update, oder?

    Wie stosse ich das dann an, das die Änderungen in die Tabellen übernommen werden? EndEdit() ??  Irgendwie muss ich das doch lostreten können? Muss "ich " dann für jede Tabelle den DataTable-Update(Tabelle) aufrufen und davor noch den SqlCommandbuilder erzeugen? Ist das der irchtige weg? Hast du mal ein Beispiel dafür?

    Dienstag, 8. Mai 2012 08:27
  • Also bisher habe ich noch keinen plassen Schimmer, wieso das nicht geht. Wenn ic nur eine Tabell dem DataGrid zuweise, dann funktioniert es wenn ich Daten einfüge oder editiere. Mit der gesamten DataView geht das leider nicht. Ich nehme die View und wandle sie zu einer DataTable und greife jede Row auf Veränderung.

    Leider hat aber keine Row einen dementspechenden Status, alle stehen auf "Added". ?? Hatte zuvor mal probiert, wenn alle Daten im DataGrid geladen sind ein AcceptChanges() durchzuführen. Leider hat das auch kein Erfolg gebracht.

    Hat jemand einen Tipp für mich? So etwas mit mehreren Tabellen hatt ich auch in dieser Form noch nie gemacht, aber wenn das funktioniert wäre das ja eine tolle Sache.

    Dienstag, 8. Mai 2012 12:18
  • Wenn Du die Daten in eine neue Tabelle kopierst, wie soll dann die Originaltabelle von den Änderungen etwas mitbekommen?
     
    AcceptChanges sollte nur in wirklich begründeten Fällen angewendet werden, da mit AcceptChanges die Rowstates zurückgesetzt werden und damit keine Information mehr als Basis für eine Synchronisation der internen Daten mit den Daten in der externen Datenbank zur Verfügung steht.
     
    Ich habe bisher noch nicht verstanden, was Du mit mehreren Tabellen machen willst. Die Oberfläche kann in einer komplexen Bindung (z.B. ein Grid) nur eine Datenquelle nutzen. Über DetailsTemplate können auch eingebettete Daten angezeigt bzw. bearbeitet werden. Die Daten für das DetailsTemplate müssen in den Daten für das Grid eingebettet sein. Das geht mit einem nicht typisierten DataSet nicht. Dazu musst Du ein typisiertes DataSet anlegen, am einfachsten mit dem Designer. Ein nicht typisiertes DataSet kann nur eine Tabelle als “flache” Ansicht bereitstellen.
     
    --
    Viele Gruesse
    Peter
    Dienstag, 8. Mai 2012 14:37
  • Hallo Peter, ich schildere nochmal mein Problem. Ich muss Daten aus drei Tabellen auswerten (kommen von einem andern System). Die eine Tabelle1 liegt in einer annderen Datenbank und die Daten der Tabelle1 werden nur gelesen und keien Änderungen daran vorgenommen. Die Tabelle2 und Tabelle3 liegen in der gleichen Datenbank. In Tabelle2 werden auch keine Änderungen vorgenommen. In Tabelle3 sollen über das DataGrid Änderungen durchgeführt werden können.  Wären alle Tabellen schon mal in der gleichen Datenbank, könnte ich alle benötigeten Spalten der Tabellen über "Join" in das DataSet einlesen. Leider geht das aber halt mal nicht, die Daten sind voneinander getrennt. Nun lese ich alle drei Tabellen separat ein und lege jede Tabelle in das gemeinsame DataSet. Nun mal zu den drei Tabellen, damit du eine Vorstellung bekommst. Tabelle1 beinhaltet Werkzeugdaten (Auftragsnummer ist Verbindungsschlüssel zu Tabelle2 und Tabelle3). Tabelle2 beinhaltet Mahndaten zu den Daten inTabelle1.

    Tabelle3 soll Vermerke vom User zur (Manager der Aufträge) Tabelle3 machen. So, damit der Manager alle Daten sieht (er muss zu jeder Auftragsnummer alle Daten der drei Tabellen sehen), visualisiere ich die in einem DataGrid. Dazu muss ich die Daten der drei Tabellen ja erstmal in einer Tabelle vereinen. Also habe ich erst mal von Tabelle1 zu Tabelle2 und von Tabelle1 zu Tabelle3 eine DataRelation erzeugt.

    Dann bin ich hingegegangen und habe die Tabelle1 vom DataSet um die nötigen Spalten von Tabelle2 und Tabelle3 erweitert. Alle Datensätze der Werkzeuge sind ja schon in Tabelle1 vorhanden. Dann habe ich diise Datensätze um die Daten der Tabelle2 und Tabelle ergänzt. Somit habe ich alle vorhandenen Daten erst mal vereint, und kann diese dann einer DataVew zuweisen, damit ich auch Filterienstellungen vornehmen kann. Diese DataView weise ich dem DataGrid zu, somit werden im dort alle Datensätze mit den zusammengefügten daten aus allen drei Tabellen angezeigt. Vielleicht kannst du dir jetzt mal ien besseres Bild von dem Problem machen. Diese Vorgehensweise müßte doch so funktionieren, oder? Die Visualisierung klappt einwandfrei, außer das speichern von geänderten Daten inBezug auf Tabelle3, wiel das die einzigen Änderungen sind, die der User machen soll. Bis jetzt bin ich noch zu keinem Ergenis gekommen.

    Das Binding sollte doch klar sein, indem ich dem DataGrid.ItemSource = DataView.CopyToTable()  zuweise. Oder muss ich noch irgendwie den Mode angeben?

    Dienstag, 8. Mai 2012 20:00
  • Jetzt ist alles etwas klarer.
     
    Grundlage ist, dass Tabelle 3 geladen, geändert und rückgespeichert wird. Demnach ist Tabelle3 zu binden und dann auch das Update mit Tabelle3 auszuführen. Damit der Anwender auch Information aus Tabelle 1 und 2 sieht, ist Tabelle3 im dataSet mit entsprechenden Ausdruckspalten zu versehen, die auf Felder in den Tabellen 1 und 2 verweisen.
     
    --
    Viele Gruesse
    Peter
    Dienstag, 8. Mai 2012 20:18
  • Hallo Peter, ich kann das nachvollziehen. Jetzt habe ich das schon angefangen im Code umzustellen. Ich lese zuerst alle drei Tabellen in das DataSet ein. Tabelle1 hat 70000 Datensätze, Tabelle2 100 Datensätze, Tabelle3 noch drei Datensätze.

    Dann habe ich Tabelle drei um die nötigen Spalten erweitert aus Tabelle1 und Tabelle2. Danach habe ich begonnen, die identischen Datensätze von Tabelle 1 und Tabelle3 in die Tabelle3 einzutragen. Dann bauche ich aber alle auch alle Datensätze in der Tabelle3, die noch keine Zurodnung zur Tabelle1  haben, da der User hier ja Einträge vornehmen kann. Und diese Prozedur dauert sehr, sehr lange. das kann ich nicht vertreten. Wie könnte man das beschleunigen?

    Donnerstag, 10. Mai 2012 05:38
  • Hallo Peter, ich kann das nachvollziehen. Jetzt habe ich das schon angefangen im Code umzustellen. Ich lese zuerst alle drei Tabellen in das DataSet ein. Tabelle1 hat 70000 Datensätze, Tabelle2 100 Datensätze, Tabelle3 noch drei Datensätze.

    Dann habe ich Tabelle drei um die nötigen Spalten erweitert aus Tabelle1 und Tabelle2. Danach habe ich begonnen, die identischen Datensätze von Tabelle 1 und Tabelle3 in die Tabelle3 einzutragen. Dann bauche ich aber alle auch alle Datensätze in der Tabelle3, die noch keine Zurodnung zur Tabelle1  haben, da der User hier ja Einträge vornehmen kann. Und diese Prozedur dauert sehr, sehr lange. das kann ich nicht vertreten. Wie könnte man das beschleunigen?

    Was mir da einfällt wäre folgendes: Ich arbeite wie gewohnt weiter, die Daten sind soweit organisiert (sind im Moment wieder alle in der Tabelle1 zusammengefasst, hatte die  ja zuerst erweitert gehabt) und das Laden und zusammenvereinen geht sehr schnell. Wenn ich einfach nur die Spalten von Tabelle1 die in der Mahnliste sind (also der Tabelle die alle Daten der drei Tabellen beinhaltet) über Mode (OneWay / TwoWay) in der CodeBehind-Datei explizit an das DataGrid binden könnte und die Bindung auf die Tabelle3 mit der betreffenden Spalte zeigen lassen kann. Wäre sowas möglich ? WIe mache ich das aber? Bisher habe ich immer nur komplette Tabellen an ein DataGrid gebunden?


    Donnerstag, 10. Mai 2012 05:51
  • Du solltest Dir Gedanken zur Bedientechnologie machen. Kein Anwender kann in einem Grid mit 70000 Zeilen vernünftig arbeiten (sowohl was die zeit betrifft, als auch was den Inhalt betrifft).
    --
    Viele Gruesse
    Peter
    Donnerstag, 10. Mai 2012 09:08
  • Da Du nur in Tabelle3 schreiben willst, sollten auch nur die Daten aus Tabelle3 gebunden werden. Um Daten aus den Tabellen 1 und 2 zu sehen, sollte aus Tabelle3 über berechnete Spalten auf die gewünschten Spalten aus den Tabellen 1 und 2 verwiesen werden.
     
    Um einen neuen Datensatz hinzufügen, müssen die Beziehungen (Fremdschlüssel) im neuen Datensatz gesetzt werden. Das sollte mit einer zusätzlichen Detailansicht realisiert werden. In dieser Ansicht kann auch die Bedientechnologie zur Auswahl eines Datensatzes aus den 70000 Datensätzen der Tabelle1 implementiert werden.
    --
    Viele Gruesse
    Peter
    Sonntag, 13. Mai 2012 18:41
  •  Kein Anwender kann in einem Grid mit 70000 Zeilen vernünftig arbeiten (sowohl was die zeit betrifft, als auch was den Inhalt betrifft).

    Hallo Peter, dazu habe ich Filter-Statements, damit der Verwalter den Überblick nicht verliert.

    Nun aber zum eigentlichen. Ich komm so einfach nicht in die "Hufe". Ich brauche jetzt eine gute Idee. Meine Oberfläche und das Programm funktionieren soweit, das Daten abrufen ist sehr schnell. Mein Problem ist doch einfach nur das "erkennen" oder das "ausfindig machen" der geänderten Daten die "Tabelle3" betreffen. Wenn ich diese Abfragen kann, dann könnte ich diese Daten aus dem DataGrid holen und über die DataSet-Tabelle zurück in die Datenbank schreiben. Das wäre doch schon alles.

    Ich muss aber jeden Datensatz aus Tabelle1 mit Tabelle2 und Tabelle3 verbinden und visualisieren, damit ein kompletter Artikel mit all seinen Daten sichtbar ist (so wie eine Maschine aus ihren Einzelteilen besteht). Dazu benutze ich das DataGrid.

    Hier jetzt nochmal Ideen von mir (ich generiere alles soweit in Code Behind !!!):

    1. Alle Daten der drei Tabellen in eine Tabelle vereinen, wo alle Spalten DBNull-Werte erlauben. Somit brauchen nicht alle Spalten von Tabelle2 und Tabelle2 belegt werden (Geschwindigkeitsvorteil bei 70000 Datensätze in Tabelle1). Diese Tabelle dann an das DataGrid binden. Wird ein Button "sichern" geklickt, alle Datensätze die "modified" oder "added" sind abfragen und in DataSet.Tabelle3 eintragen. Dann die DataSet.Tabelle3 in die Datenbank zurückschreiben.
    2. Wie gehabt, die drei Tabellen in eine Tabelle vereinen, und an das DataGrid binden. Aber nur die Spalten der Tabelle3 über Mode aktualisieren lassen. habe aber keine Ahnung ob das geht, und vor allem wie das in dieser Konstellation genau geht, da ich alles in Code Behind generiere.

    Nun Peter, kannst du mir dabei helfen eien vernünftige Lösung zu finden? Kannst du dir das überhaupt genau vorstellen, was ich da genau mache und was ich brauche? Ansonsten erkläre ich das nochmal genauer.

    Montag, 14. Mai 2012 08:23
  • Ich habe vermutlich verstanden, was Du machen willst. Du hast eine Tabelle, in der Du ändern incl. hinzufügen willst. Das ist Deine Tabelle 3. Diese Tabelle referenziert auf Masterdaten (Deine Tabellen 1 und 2), aus denen bei Neuanlage eines Datensatzes über Filteroptionen (z.B. aus den 70000 Nachschlagesätzen der Tabelle 1) ausgewählt werden soll. 
     
    Eine vernünftige Lösung habe ich Dir schon umrissen. Ich verstehe nicht, warum Du das nicht so machen willst bzw. kannst, wie ich es beschrieben habe.
     
    Wenn Du es so wie beschrieben machen willst, dann deklariere im Client eine Tabelle, die Du mit JOIN-Klauseln aus den verschiedenen Tabellen Deiner externen Datenbank lädst. Alle Spalten, die aus Tabelle 1 oder 2 gefüllt wurden, zeigst Du mit ReadOnly an und die zu Tabelle 3 gehörenden Spalten schreibst Du dann mit DataAdapter bzw. TableAdapter in die Datenbank zurück. Ggf. musst Du die Command-Objekte selbst erzeugen oder über eine gezielte Reihenfolge der Deklarationen des typisierten DataSets teilweise vom Designer erzeugen lassen.
     
    --
    Viele Gruesse
    Peter
    Montag, 14. Mai 2012 11:36
  • Hallo oema,

    Ich möchte Dich bitte folgendes lesen und die Beiträge die Dir geholfen haben zu bewerten. Vielen Dank.

    Nutzen Sie die Bewertungsfunktionen ("Antwort" und "Hilfreich") in den MSDN Foren! Unter anderem können andere später eine Lösung schneller finden. Es ist also wünschenswert, dass die fragenden (Benutzer) die Postings anderer Beantworter bewerten.
    Hier dazu die wichtigsten Anhaltspunkte aus den
    Forenregelnund FAQs.

    Lösungsbeiträge als „Die Antwort“ markieren
    Bitte markieren Sie den Beitrag, der zur Lösung geführt hat, als "Die Antwort". Durch Bewerten eines Beitrags als "Die Antwort" können andere Teilnehmer die Lösung schneller finden. Außerdem können Sie dem Benutzer, der die Antwort eingereicht hat, für seinen Beitrag danken und zur Steigerung der Antwortqualität in der Diskussionsgruppe beitragen.
    [Quelle:
    Forenregeln]

    Bitte markiere den/die Beiträge als Antwort, die dir geholfen haben, dein Problem zu lösen. Das ist zum einen eine Anerkennung für die Autoren dieser Beiträge, zum anderen hilft es zukünftigen Lesern, sich in diesem Thread besser zu orientieren und Antworten auf ihre Fragen schneller zu identifizieren.

    Wie zeige ich an, dass meine Frage durch einen Beitrag beantwortet wurde?

    Wie bewerte ich einen Beitrag als hilfreich? Um einen Beitrag als hilfreich zu bewerten, klicken Sie in einem beliebigen Beitrag auf Als hilfreich bewerten. Sie können Ihre Stimme nur einmal für einen Beitrag abgeben.
    [Quelle:
    Häufig gestellte Fragen]

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Donnerstag, 17. Mai 2012 16:24
    Moderator
  • Hallo oema,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Montag, 21. Mai 2012 16:45
    Moderator
  • Hallo, habe das Projekt erst mal ruhen lassen, da ich erst mal eine Lösung gefunden habe. Damit bin ich aber noch nicht zufrieden. Ich würde gerne wissen, wie ich das mache wie Peter Fleischer das meinte, das ich nur die Spalten der Tabelle 3 an das DataGrid binde. Kann man mal ein kleines Beispiel aufzeigen?

    Lösungsansatz von Peter: ==>

    Da Du nur in Tabelle3 schreiben willst, sollten auch nur die Daten aus Tabelle3 gebunden werden. Um Daten aus den Tabellen 1 und 2 zu sehen, sollte aus Tabelle3 über berechnete Spalten auf die gewünschten Spalten aus den Tabellen 1 und 2 verwiesen werden.

    Meine Fragen:

    a.) Wie binde ich nur die Spalten aus Tabelle3 an das DataGrid (in code behind), obwohl die Spaten von Tab1 +2 auch in der Tabelle vorhanden sind??

    b.)Wie mache ich das mit berechnteten Spalten in code behind - Datei die nur auf die Tab1 + 2 verweisen??

    Habt ihr dazu evtl. zwei kleine Beispiele?

    Montag, 21. Mai 2012 21:12