Darstellung einer mit Linq to Dataset gruppierten Liste

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Darstellung einer mit Linq to Dataset gruppierten Liste

    Hallo liebe Leuts,
    ich habe eine Anwendung mit einem Dataset, das 2 verknüpfte Tabellen enthält. Es geht dabei um die Protokollierung der Prüfung von Geräten.
    Die Tbl_Geräte enthält eine Auflistung aller vorhandenen Geräte mit ID, Bezeichnung, Aufnahmedatum usw.
    Die Tbl_Prüfungen enthält u.a. das Prüfdatum, die GeräteID, den Namen des Prüfers und das Prüfergebnis (OK/nichtOK)
    Die Darstellung der Views in den DGVs funzt soweit, was Geräteerfassung, Prüfhistorie der Einzelgeräte und die Darstellung aller Prüfungen angeht.

    Jetzt möchte ich aber zu jedem Gerät die jeweils letzte Prüfung in ein DGV schreiben. Die Filterfunktion der Bindingsource bekommt das aber nicht hin. Deswegen habe ich mit Linq to Dataset die Prüfungen nach Geräten und Datum sortiert und anschließend nach Geräten gruppiert. nun kann ich jeweils den 1. Eintrag der Liste ausgeben.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function GetLetztePrüfung() As Collection
    2. Dim gruppiertePrüfungen = From Prüfung In DS_Geräte.Tbl_Prüfungen _
    3. Select Geräte_ID = Prüfung.ID_Ger, _
    4. Prüfdatum = Prüfung.Datum, _
    5. Prüfer = Prüfung.ID_Prüfer, _
    6. Status = Prüfung.OK
    7. Order By Geräte_ID, Prüfdatum Descending _
    8. Group By Geräte_ID Into Prüfungen = Group
    9. GetLetztePrüfung = New Collection
    10. For Each gruppe In gruppiertePrüfungen
    11. GetLetztePrüfung.Add(gruppe.Prüfungen(0))
    12. Next
    13. End Function

    Nun möchte ich diese Collection als Tabelle an ein DGV ausgeben. Dazu schreibe ich also die Collection in eine Bindingsource (im Designer auf die Form gezogen und binde des an das DGV.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub TabPage1_Enter(sender As System.Object, e As System.EventArgs) Handles TabPage1.Enter
    2. BS_Status.Clear()
    3. For Each _row In GetLetztePrüfung()
    4. BS_Status.Add(_row)
    5. Next
    6. DGV_Status.DataSource = BS_Status
    7. End Sub


    Das mit der Collection is mir aber irgendwie komisch, weils keine richtige Datarow is. Ich hätte ja viel lieber mit dem Linq-Ausdruck direkt die Datarows aus der Prüfungstabelle gezogen (Das hattich schon passend). Dann habich eine Tabelle vom Typ der Prüfungstabelle erstellt (Dim Tab as DS_Geräte.Tbl_Prüfungen), sie dem DGV als Datasource zugeordnet(damit ich die Columns stylen kann) und wollte der dann die gewonnenen Zeilen Adden. Da hieß es denn, dass diese Zeilen bereits zu einer anneren Tabelle gehören. So mußtich dan auf den oben geschilderten Plan umsteigen.
    Ich bin sicher, dasses da ne einfache Lösung gibt, die Zeilen aus dem Linq direkt in eine passende Tabelle zu schieben, aba wie??

    Ich hoffe, ich konnte das verständlich rüberbringen...
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    Vatter schrieb:

    Ich bin sicher, dasses da ne einfache Lösung gibt, die Zeilen aus dem Linq direkt in eine passende Tabelle zu schieben

    wenndedich da man nicht irrst.
    Die Linq-Group - Klausel produziert anonyme Klassen, und die sind kaum zu iwas zu gebrauchen.
    Weil man kann sie an keine annere Methode weitergeben, weil die Methode den Parameter nicht deklarieren kann, weil die ja anonym sind.
    Also musste doch eine ordentliche Klasse programmieren, mit ordentlichen Membern, und die anonymen Linq-Sachen da schön einsortieren.

    Wennde eh mit typ Datasets unterwegs bist, kannste eine extra DataTable dafür anlegen, und der DataRows adden, die aus dem Linq-Zeugs befüllt wurden.

    Dann kann man da auch ein DGV schön für designen.

    Allerdings kannst du sone Query auch direkt einem DGV als DataSource andrehen, und das Autogeneriert dazu so leidlich geeignete Spalten.
    Aber so ein Autogeneriertes DGV kannstedann nur per Code designen, und die Werte kannste absolut auf keine Weise verarbeiten, weil du keine Methode deklarieren kannst, die diese Werte erwartet.
    Aber nur zum Angugge täts reichen.

    Beachte auch, dass die Groups einen Baum darstellen. Du kriegst eine Auflistung von Groups, und jede group enthält eine Auflistung von anonymen Datensätzen.
    Danke dir,
    Das läuft ja wohl darauf hinaus, die neu anzulegende Tabelle zu Fuß Feld für Feld in einer Schleife zu befüllen. Nuja, is ja nich schlimm.
    Ich habe eben nochwas anneres ausgegraben: ImportRow sieht da auch interessant aus. Damit könnt ich die (ich nenn sie mal) ViewTbl luxorös füllen.

    Vielleicht muss ich aber auch das Datenmodell ma überlegen:
    Wenn ich die jeweils letzte Prüfung der Geräte haben will, mussich ja nicht den ganzen Datensatz in die Tabelle morkeln, sondern kann ja nur die PrüfungsID da reintun. Dann könnte ich doch über Binding wie JoinView den Rest des Datensatzes anzeigen und hätt nicht alles doppelt im Speicher?
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    man kann einer BindingSource auch statt einer Liste oder DataTable auch ein einzelnes Objekt übergeben. (ZB. eine einzelne DataRow)
    In dem Fall macht die Darstellungg als Tabellse nicht mehr wirklich Sinn, sondern man wähle "DetailView" stattdessen.

    Kommste klar damit? Ansonsten uploade ich mal ein Sample (den Fall "Datarow" als einzel-objekt müsste ich auch erstmal selbst ausprobieren).

    ErfinderDesRades schrieb:

    Kommste klar damit?

    Nich wirklich. :huh: Ich werd ma die ganzen Ideen und Hinweise auf mich wirken lassen.
    Heut kommich da bestimmt nicht mehr zu, aba wenn der Wetter sooo besch... bleibt :D kann ich noch so manches rumspielen. Es drängt ja nicht, weils zwar funzt, mir aber wie gesagt die Lösung, die ich da grade habe, unsauber vorkommt. Und verstehen willmans ja auch noch.

    Mein Modell der Auswertung muss ich sowieso nochmal durchschauen. Es gibt schließlich auch Gräte, die noch ganicht geprüft wurden. Bei meiner Abfrage werden die einfach unterschlagen (was fürneSauerei). Ich habe ja in der Tabelle Geräte den nächsten Prüftermin (= letztes Prüfdatum + Prüffrist, wenn Prüfung OK, sonst =Prüfdatum).Damit ist der Status des Gerätes an Hand dieses Datums eigentlich klar. Den nutz ich ja schon, um den DGV RowCelldefaultstyle des DGV anzupassen (rot/grün). Wenn ich jetzt gleichzeitig die PrüfungsID in der GeräteTbl ablege hab ichs doch schon.

    Danke dir,
    ich meld mich, wenns nochma Probleme gibt.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Hallo Erfinder,
    ich hätt ja gern das gesamte Projekt hochgeladen, aber das hat sich trotz Zip auf 33MB aufgeplustert. Deswegen hier nur mal den Teil mit der besagten Auswertung:
    Jedes Gerät mit seinen Daten und denen der letzten Prüfung.
    Mit ner separaten Datasettabelle ging des recht gut. Ich brauchs ja eigentlich nur als Abschluß, damit ich eine Grundlage zum Ausdrucken hab. Die Tabelle lässt sich ja vorzüglich als xml speichern oder als csv exportieren usw.

    Ich hab jetz ne komplett abgespeckte Version hochgeladen mit ner .xml im Debug-Ordner. Die Tabelle wird im Formload vom xml ins Dataset geladen. Mit dem Startbutton wird dann die Tabelle gefüllt...
    Wenn was fehlt, sag bitte bescheid.

    TestProjekt.zip
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    guck - ich hab gestern noch jmd anners gefunden, bei dem ich son Group-Dingsbums einbauen konnte :)

    [VB 2010] Hilfe bei SQL-Abfragen

    Jetzt gucke ich da rein, und verfalle auf eine annere Idee:
    "Letzte Prüfung" könnte doch eine Eigenschaft der Geräte sein.


    Oder man nutzt eine zusätzliche Relation, die nur bei den neuesten Prüfungen auf das Gerät verweist, ansonsten aber immer auf Null gesetzt bleibt.

    Dann könnteman einen Bindingsource-Filter setzen, der darauf filtert, ob dieser GeräteVerweis gesetzt ist.
    Ich bastel mal.

    Ansonsten, die bestehende Beziehung: ich würde die mit Löschweitergabe konfigurieren, inne DB wie im Dataset.
    Btw: was machst du da mit der Geräteklasse? Könnte man doch auch inne DB anlegen, dass man alles beisammen hat?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    AOIDatenDataSet_Linie3RowBindingSource.DataSource = grps.First.Group.First
    Is ja interessant! :thumbsup:

    "Letzte Prüfung" könnte doch eine Eigenschaft der Geräte sein.
    Das habich im Dataset jetzt schon so drin (Spalte in GeräteTbl letztePrüfung) wo die PrüfungsID gespeichert wird. Nur dass ich die Tabelle handisch fülle.

    ErfinderDesRades schrieb:

    Oder man nutzt eine zusätzliche Relation, die nur bei den neuesten Prüfungen auf das Gerät verweist, ansonsten aber immer auf Null gesetzt bleibt.

    Ich möchte die Prüfungen nicht vom Gerät "abhängen", damit man schauen kann, was bei der Prüfung davor los war.

    ErfinderDesRades schrieb:

    Ansonsten, die bestehende Beziehung: ich würde die mit Löschweitergabe konfigurieren, inne DB wie im Dataset.
    Das is sone Sache....Das mit der Löschweitergabe hab ich hier noch nicht so richtig gelöst bekommen, weil ich da keine Datenbank benutze, sondern nur mit Write/ReadXML arbeite. Und da gibs ja keine Tableadapters. Wenn ich da im Dataset die Löschweitergabe aktiviere gibs da immer Fehlers :(. Das hab ich bis jetzt so hier "gelöst":

    VB.NET-Quellcode

    1. ' Löscht das markierte Gerät aus der Biningsource
    2. Private Sub Btn_Löschen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn_Löschen.Click
    3. Me.Validate()
    4. Dim _id As Integer = ActiveGeräteRow.ID
    5. For n = DS_Geräte.Tbl_Prüfungen.Rows.Count - 1 To 0 Step -1
    6. Dim temp As DS_Geräte.Tbl_PrüfungenRow = CType(DS_Geräte.Tbl_Prüfungen.Rows(n), PruefApp.DS_Geräte.Tbl_PrüfungenRow)
    7. If temp.ID_Ger = _id Then
    8. DS_Geräte.Tbl_Prüfungen.RemoveTbl_PrüfungenRow(temp)
    9. End If
    10. Next
    11. Tbl_GeräteBindingSource.RemoveCurrent()
    12. End Sub



    ErfinderDesRades schrieb:

    was machst du da mit der Geräteklasse? Könnte man doch auch inne DB anlegen, dass man alles beisammen hat?
    Ich hatte die auch schon als Tabelle im dataset angelegt. Dann wird das aber auch in der xml gespeichert, die für jeden zugänglich ist. Manipulationen verändern dann den Prüfungsablauf. darum "hart programmierte" Klassen.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    also habichmal was zusammengewurstelt.

    Die neue Relation ist dem irrsinnigerweise Gerät übergeordnet (was vom Datenmodell ja garnet stimmt - bestenfalls eine 1:1-Relation besteht, aber sowas kann Dataset nicht).
    Jdfs, diese komische Relation macht genau einen Prüfung-Datensatz zu einer Property des Geräts - die Property wird auch generiert. Der ForeignKey hier ist nullable, sodaß ein Gerät auch ganz ohne Prüfung ein gültiger Datensatz ist.
    Das ist eine ganz annere Verwendung von DataRelation, als wofür sie eiglich da ist.

    Ach - ich hab auch noch eine berechnete Spalte drangemacht, die den letzten PrüfTermin auch anzeigt. Normalerweise täte ich ja comboColumns verwenden, aber da diese Spalte Nullable ist, würde das zu ungültigen Combobox-Werten führen (während eine TextboxColumn Null-Werte verträgt). Die Nullwerte fallen übrigens schon von selbst sehr schön auf im DGV.


    Dann habich Prüfung_RowChanged abonniert, und immer wenn eine Prüfung zugefügt wird, wird diese als LetztePrüfung ins Gerät eingetragen

    VB.NET-Quellcode

    1. Private Sub Prüfung_RowChanged(ByVal sender As Object, ByVal e As Tbl_PrüfungenRowChangeEvent)
    2. If e.Action <> DataRowAction.Add Then Return
    3. Dim rwGeraet = e.Row.Tbl_GeräteRow
    4. 'ein mir unverständlicher DataGridViewError tritt an der comboBoxCell auf,
    5. 'wenn man nachträglich einer gerätRow eine PrüfungsRow vorsetzt.
    6. 'ich weiß nur einen Workaround, das zu unterdrücken.
    7. Dim dummiError As DataGridViewDataErrorEventHandler = Sub(s, ee) ee.ThrowException = False
    8. AddHandler Tbl_PrüfungenDataGridView.DataError, dummiError
    9. rwGeraet.Tbl_PrüfungenRow = e.Row
    10. RemoveHandler Tbl_PrüfungenDataGridView.DataError, dummiError
    11. End Sub
    Sehr verwirrt bin ich über den DataError, der Auftritt, wenn man das Prüfungs-Grid mit einer ComboColumn ausstattet (siehe Kommentar)

    Vatter schrieb:

    Ich möchte die Prüfungen nicht vom Gerät "abhängen", damit man schauen kann, was bei der Prüfung davor los war.

    Deswegen ja eine zweite Relation - die berührt die eigentliche Relation garnet.

    Vatter schrieb:

    Das is sone Sache....Das mit der Löschweitergabe hab ich hier noch nicht so richtig gelöst bekommen, weil ich da keine Datenbank benutze, sondern nur mit Write/ReadXML arbeite.
    Löschweitergabe kann man sowohl inne DB einrichten, also auch im Dataset - ist in keinem Fall ein Problem.
    Dann kannste deinen ButtonLöschenKlick bis auf die letzte Zeile zusammenstreichen.

    Vatter schrieb:

    Dann wird das aber auch in der xml gespeichert, die für jeden zugänglich ist. Manipulationen verändern dann den Prüfungsablauf.

    Also wenn da geschummelt wird, musste denkich alle Daten sichern, nicht nur eine bestimmte Tabelle.

    richtige Hacker kannst durch hart verdrahtete Daten garnet abhalten, und OttoNormalVerbraucher ist schon abgewehrt, wennde die Daten einfach über einen Gzip-Stream speicherst - das ist ohne spezielles Tool auch nicht lesbar, denn GZip ist kein Zip-Format.
    gugge Stream-Konzepte
    Dateien
    • TestProjekt00.zip

      (29,45 kB, 126 mal heruntergeladen, zuletzt: )

    ErfinderDesRades schrieb:

    Also wenn da geschummelt wird, musste denkich alle Daten sichern, nicht nur eine bestimmte Tabelle.
    richtige Hacker kannst durch hart verdrahtete Daten garnet abhalten

    Nee, da wird nich geschummelt oder gehackt. Des is so:
    Im Moment sollen ja nur unsere Geräte geprüft werden (Alles was nen Stecker hat), vielleicht auch mal die von einem Kunden. Das ist so vorgeschrieben. Auch die Klasseneinteilung ist entsprechend der Geräteart vorgeschrieben (Mit Schutzleiter = Klasse 1, Schutzisoliert = Klasse2, Kleinspannung=Klasse3) Nun hat es ja keinen Sinn, den Schutzleiterwiderstand von einem Gerät zu messen, das gar keinen solchen hat.
    Die XML enthält nun quasi das Inventar und die zugehörigen Prüfungen einer Firma. Das sind also eigentlich Daten, die dem Kunden gehören (neuer Kunde=neue XML-Datei). Der soll ja auch in der Lage sein, die Daten z.B. in Excel zu importieren und dann den Ausdruck den Behörden vorlegen können.
    Die Definition für die Geräteklassen müssen also sowieso woanners gespeichert werden, da sie von der DIN vorgeschrieben und nicht kundenspezifisch sind. Geht so eine Datei inkl. der Geräteklassendefinition verloren, is des ganze Prog unnütz, weil nicht mehr nach DIN.
    Manipuliert ein Kunde die Geräte-, oder PrüfungenTabelle in der Datei, um Prüfungen vorzutäuschen, die nicht gemacht wurden, is das seine Sache. Das is so, als wennde deinen Befund vom Artzt manipulierst un mit nem gebrochenen Arm zur Arbeit gehst. Passiert was, is er der Dumme. Die Prüfung is wie beim TÜV, für nach der Prüfung festgestellte Mängel kann nur der Betrieber was. :rolleyes:

    Die Löschweitergabe funzt jetz einfach so (also nach Einstellung im Dataset) 8| . Ich hatts schonma so... (eher wohl nich, sonst wärs ja gleich gegangen)

    Vielen Dank auch für deine Mühe mit der Relation letzte Prüfung da. Das tolltse, wo ich bisher ganich dadran gedacht hab, sind so Events wie Prüfung_RowChanged. Des hat keinen Handler hinter? Also die Eventargs habich im Dataset-Designer gefunden. aber sonst bin ich da irgendwie überfordert ;( . Wie wirdndas aufgerufen (Raiseevent?).

    Edit: Ich nerv nochma.
    Du hast ja, wie allgem. üblich, im Dataset-Designer Autoincrement.Step auf -1 und im Initialize-Event des DS dann autoincrement wieder nomal an. Bei DB-Program :D mierung habichs ja verstanden, weil die DB die Nummerierung der ID vornimmt und so keine Doplungen vorkommen können.
    Bei diese Konstellation wird aber ausschließlich das DS nummerieren. Da kannes doch positiv bleibn, ohne Probleme zu machen oder? Es ist nämlich so, dass die ID auch verwendet wird, um die Geräte zu kennzeichnen. Und da muß 0815 auch 0815 bleiben. Sonst sucht der Elektriker bei einem Trockenrasierer den Schutzleiter zum Durchmessen (und das wär peinlich :D )
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Vatter“ ()

    Das Event wird per Add-/Remove-Handler abonniert bzw. abbestellt. gugge Alles über Events

    weiß nicht, ob du das schon gemacht hast, aber ist sehr empfehlenswert, mal im Objectbrowser nachzugucken, was die generierten Klassen denn so alles können.
    Und auch die untypisierten Basisklassen sind schon "mächtig gewaltig"

    Dass diese Klassifizierung iwie so umständlich als Neben-Datenmodell mit drangepatcht werden muß, verstehe ich immer noch nicht wirklich.
    Umständlich, unverständlich (damit schlecht wartbar für Leute, dies nicht programmiert haben), und schränkt natürlich das Spektrum der Möglichkeiten ein, die ein durchgängig als Dataset konzipiertes Datenmodell bietet.

    ZB weiß ich nicht, wie man etwa einen JoiningView gestalten sollte, der die Prüfungen zeigt, und eine ComboColumn bietet die Prüfungs-Klassen zur Auswahl.

    Jo, das ist wohl, was mich daran stört: Inne Wirklichkeit besteht unabweisbar die Relation PrüfungsKlasse->Prüfung, aber im Datenmodell kann sie nicht nachgebildet werden.

    Ich wäre ja schon zufrieden, wenn du eine Klasse-Tabelle anlegst, und die mw. festverdrahtet übers Programm befüllst - muß ja nicht von iwo geladen werden.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Pah...
    Ich Dussel hab jetzt erst im Laden-Sub gesehen Addhandler usw.
    Alles klar
    Sorgt das hier evtl dafür, dass DS_Geräte.HasChanges() beim Laden auf false bleibt?

    VB.NET-Quellcode

    1. Dim srcs = Me.components.Components.OfType(Of BindingSource).ToList
    2. For Each bs In srcs
    3. bs.RaiseListChangedEvents = False
    4. Next

    Dann könnt ich die Speicheraufforderung nämlich dadran koppeln, die nervt sonst ganz fürchterlich...
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    drangemacht habichs, um ComboboxColumn-Fehler zu vermeiden.
    Weil Dataset.ReadXml lädt die Tabellen nicht in der Reihenfolge, wie es von den Relationen her erforderlich wäre.
    Außerdem optimiert das die Lade-Geschwindigkeit, wenn die Databindings nicht bei jedem Datensatz rumklappern müssen.

    HasChanges setzt du mit Dataset.AcceptChanges zurück.
    Es gibt übrigens auch ein .RejectChanges - also wirklich: Objectbrauser an, und fleißig brausen.

    guck dirmal mein Framework an, das hat ja auch eine kleine Lösung für DatasetOnly. Da ist Laden Speichern, Speichern-Anfrage beim Schließen, und ein WinForm-Bug-Workaround alles mit drin. Und das Theater mit mehrfachen Datasets. Und vereinfachter Datenzugriff über die BindingSources.

    Ich bin nämlich der Auffassung, das sind alles sowas von Standard-Tasks, die gehören in eine Dll weggekapselt, sodasses jeweils mittm Einzeiler abzuhandeln ist.


    [VB 2008] DBExtensions

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    HasChanges setzt du mit Dataset.AcceptChanges zurück.
    Es gibt übrigens auch ein .RejectChanges - also wirklich: Objectbrauser an, und fleißig brausen.

    Tut mir ja sooo leid, aber mit dem Text zu AcceptChanged kann ich nix anfangen:
    Führt einen Commit für alle Änderungen aus, die an diesem System.Data.DataSet seit dem letzten Ladevorgang oder seit dem letzten Aufruf von System.Data.DataSet.AcceptChanges vorgenommen wurden.

    Auch bei RejectChanges liest sich das nich wirklich verstänlich:
    Führt einen Rollback aller Änderungen aus, die am System.Data.DataSet seit dessen Erstellung oder seit dem letzten Aufruf von System.Data.DataSet.AcceptChanges vorgenommen wurden

    Aber dafür kannst du schließlich nix (Oder? :))

    ErfinderDesRades schrieb:

    guck dirmal mein Framework an

    Werdich tun (Vielleicht versteh ichs ja)
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    ja, das stimmt leider: objectbrowser erklärt alles, ausser seine eigenen Erklärungen. :(

    aber in diesem Fall erklärts ja der Methoden-Name: Accept übernimmt alle Änderungen, und Reject weist sie zurück.
    In beiden Fällen wird bei allen DataRows der RowState auf Unchanged gesetzt, sodass die Identifizierung der Änderungen weg ist, und neue Änderungen auch neu identifiziert werden können.

    Und wenn im ganzen Dataset alle Rowstates auf Unchanged stehen, dann ergibt Dataset.HasChanges False

    Normalerweise, wenn ein DataAdapter eine Table befüllt oder abspeichert, setzt er AcceptChanges für die DataTable. Aber bei Dataset.ReadXml geschieht dieses nicht - müssteste also händisch machen - hups! - das sagte ich schon.

    Also normalerweise, wenn mit DataAdaptern gearbeitet wird: Finger weg von AcceptChanges! Weil wenn die Änderungen irrtümlich nicht mehr identifiziert sind, speichert der auch nix mehr ab.

    Edit: Ah - jetzt verstehe ich sogar tatsächlich den Text des OBs: Der setzt halt einfach vorraus, dass man sich mit Datenbanken auskennt (tu ich ja auch nicht richtig wirklich).
    Nämlich inne Datenbänkerei gibts das Konzept "Transaktion". Das bedeutet, man packt beliebig viele Daten-Operationen in eine Transaktion, und fährt die ab. Wenn nun während der Verarbeitung ein Fehler auftritt, kann man die gesamte Transaktion rückgängig machen - der sog. "RollBack".
    Andernfalls, wenn zusammenhängende Daten gespeichert werden und iwo ist was ungültiges dabei, dann könnteman zwar abbrechen, aber vmtl. wären die nun nur halb gespeicherten zusammenhängenden Daten erst recht mal ungültig.
    War hingegen die Transaktion erfolgreich, so schließt man sie durch ein "Commit" ab, was auf die Daten keine Auswirkung hat, aber es werden erhebliche Resourcen freigegeben, nämlich die ganzen vorherigen Werte mussten ja zwischengelagert werden für den Fall eines Rollbacks.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()