myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » Wie halte ich mein ViewModel aktuell nach einem Datenbank-Update?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie halte ich mein ViewModel aktuell nach einem Datenbank-Update?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
myCSharp.de
Moderationshinweis von MrSparkle (26.10.2020 12:21):

Abgeteilt von  Wie kann man unter WPF ein neues Fenster MVVM-konform öffnen?
 
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 155
Entwicklungsumgebung: Visual Studio 6.0 Enterprise


JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hey noch eine weiterführende Frage:

Ich arbeite in meiner Datenbank mit "Order"-Objekten, diese mappe ich mir in "OrderViewModels" für WPF,...

Speichere ich z.B. ein Objekt ab, lese ich danach wieder die Datenbank aus.

C#-Code:
            // "Order"-Objekte aus der Datenbank
            var orders = await _SqlRepo.GetOrders();
            // Liste mit ViewModels (werden in Window abgerufen)
            _Orders.Clear();

            foreach(var order in orders)
            {
                var vm = new OrderViewModel(order);

                _Orders.Add(vm);
            }

Durch das Clearen gehen ja jedesmal die Referenzen verloren, wenn z.B. ein Fenster mit Details das jeweilige OrderViewModel noch verwendet. Das funktioniert zwar, ich kann Änderungen dann aber nur noch an einer Stelle tracken.

Gibt es ein fertiges Pattern mit dem ich erst die bestehenden ersetze (z.B. anhand OrderID identifiziere), dann nicht mehr vorhandene (gelöschte) entferne und neu hinzugefügte, neu erstelle?
Das kann man natürlich alles von Hand machen, ich schätze das Problem ist aber sicher schon öfter vorgekommen, ich weiß nur nicht nach was ich suchen soll.
24.10.2020 20:23 Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 928


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

... dann lerne doch LINQ. Damit isr dein gezeigter Code ein Zweizeiler. Und für das Anfügen und Entfernen gibt es Except, Union und Where.
26.10.2020 07:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.565
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@witte: Das würde aber nichts an dem Problem ändern.

@JimStark: Kannst du bitte zukünftig  [Hinweis] Wie poste ich richtig? beachten, besonders Punkt 1.2: Nur ein Thema pro Thread? Wir müssen jedesmal deine Beiträge verschieben...

Zu deinem Problem: Wenn der Benutzer das ViewModel geändert hat, und die Änderungen in die Datenbank geschrieben wurden, dann ist doch das ViewModel auf dem aktuellen Stand. Wozu sollte man dann alles noch einmal neu laden?

Das wäre nur notwendig, wenn die Daten außerhalb der Anwendung geändert wurden. Und dann darfst du die ViewModels eben nicht ersetzen, sondern mußt die vorhandenen anpassen.
26.10.2020 12:26 Beiträge des Benutzers | zu Buddylist hinzufügen
Palladin007 Palladin007 ist männlich
myCSharp.de-Mitglied

avatar-4140.png


Dabei seit: 03.02.2012
Beiträge: 1.363
Entwicklungsumgebung: Visual Studio 2019
Herkunft: NRW


Palladin007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab mir dafür mal eine generische Liste geschrieben, die neben INotifyCollectionChanged auch passende Methoden bietet, die vorhandene Objekte ersetzen kann.
Intern war es im Wesentlichen ein Dictionary mit der ID als Key und der ViewModel als Value.
Die ViewModels mussten dann natürlich Funktionalität zum Aktualisieren der Daten (Ein Interface mit einer UpdateData(TModel)) haben und die Liste hat dann aus den übergebenen Models die IDs gesucht und entsprechend aktualisiert, erzeugt oder entfernt.

Ein Pattern in dem Sinne gibt es nicht (ode ist mir nicht bekannt), da das Problem viel zu spezifisch ist oder sein kann.
26.10.2020 20:48 Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 155
Entwicklungsumgebung: Visual Studio 6.0 Enterprise

Themenstarter Thema begonnen von JimStark

JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

danke für eure Tipps,

habe es mir jetzt doch nochmal etwas umgeschrieben, das funktioniert soweit jetzt. Falls jemand es brauchen sollte:

C#-Code:
            // Modelle von Datenbank beziehen:
            var orders = _SqlRepo.GetOrders();
            orders.Wait();


            // Modelle die in ViewModel Liste bereits referenziert sind:
            var ordersToReplace = _Orders.Where(
                c =>
                orders.Result.FirstOrDefault(old => old.OrderID == c.OrderID) != null)
                .ToList();


            // vorhandene ViewModels ersetzen:
            ordersToReplace.Select(
                c =>
                c = new OrderViewModel(
                    orders.Result.Where(c => c.OrderID == c.OrderID).First()
                    )
                );

            // ViewModels, für die es kein Modell gibt ==> löschen
            var ordersToDelete = _Orders.Where(
                vm =>
                orders.Result.FirstOrDefault(model => model.OrderID == vm.OrderID) == null)
                .ToList();

            foreach(var orderToDelte in ordersToDelete)
                _Orders.Remove(orderToDelte);


            // Models, für die es kein ViewModel gibt ==> hinzufügen:
            var ordersToAdd = orders.Result.Where(
                c => _Orders.FirstOrDefault(vm => vm.OrderID == c.OrderID) == null)
                .ToList();

            // ViewModel für Modell erstellen & hinzufügen:
            foreach (var order in ordersToAdd)
                _Orders.Add(new OrderViewModel(order));
27.10.2020 16:59 Beiträge des Benutzers | zu Buddylist hinzufügen
dannoe
myCSharp.de-Mitglied

Dabei seit: 24.11.2015
Beiträge: 119
Entwicklungsumgebung: VS2005-VS2017


dannoe ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ersatz du hier mit:

C#-Code:
// vorhandene ViewModels ersetzen:
ordersToReplace.Select(
    c =>
    c = new OrderViewModel(
        orders.Result.Where(c => c.OrderID == c.OrderID).First()
        )
    );

... nicht genauso das komplette Objekt (inkl. Referenz) wie mit dem Code in deinem initialen Post?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dannoe am 27.10.2020 17:54.

27.10.2020 17:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 155
Entwicklungsumgebung: Visual Studio 6.0 Enterprise

Themenstarter Thema begonnen von JimStark

JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich glaube ich habe mein Problem nicht deutlich genug erläutert.

Als Beispiel habe ich ein Objekt der ViewModel-Liste gebunden, und zeig in einer TextBox ein Feld davon. Wenn ich zwischenzeitlich die Objekte neu lade und danach die TextBox änder, konnte ich in der Liste die Änderung nicht mehr nachverfolgen, da ja die Referenz verloren ging (durch Clear).
Mit dem Code geht es jetzt. Also die "Referenz" ist scheinbar die selbe, sie wurde nur ersetzt.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JimStark am 27.10.2020 18:04.

27.10.2020 18:03 Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.565
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der Code, den dannoe gepostet hat, ersetzt genau gar nichts :)
Es werden neue OrderViewModels erzeugt, und dann verworfen, da mit dem Ergebnis nichts gemacht wird. Da die Enumeration selbst gar nicht durchlaufen wird, z.B. mit ToList(), werden noch nicht einmal die OrderViewModels erzeugt.

Entweder ist der Code aus dem Zusammenhang gerissen, oder du hast nicht richtig getestet. Am besten schreibt man sich für so etwas Unit Tests, dann kannst du sicher sein, daß der Code macht, was er soll. Siehe dazu:  [Artikel] Unit-Tests: Einführung in das Unit-Testing mit VisualStudio

Aber was du zu der TextBox schreibst, klingt eher nach einem Problem mit dem UI-Design.
27.10.2020 18:51 Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 155
Entwicklungsumgebung: Visual Studio 6.0 Enterprise

Themenstarter Thema begonnen von JimStark

JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du hast recht, das ist mir gar nicht aufgefallen. Ich habe jetzt eine Update Methode dafür geschrieben. Damit geht es jetzt. Danke!
28.10.2020 10:22 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Monat.
Der letzte Beitrag ist älter als ein Monat.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 30.11.2020 12:03