Bindung nach Entity Model first aktualisiert Daten nicht!

  • WPF

Es gibt 118 Antworten in diesem Thema. Der letzte Beitrag () ist von Jeiss.

    ErfinderDesRades schrieb:

    Aber - ähm - zu MVVM habich mich doch grad garnet geäussert? Was (ich darf sagen: "unsere") Verständnis-Probleme verursachte war doch die Dependency-Injection

    Doch, hätten wir hier kein MVVM bräuchten wir auch keine Services. Die Trennung durch das Pattern macht das ganze ja so "übel". Ja, übel. Ich bin ja auch der Meinung das es mehr oder weniger übel ist, aber es ist nun mal so.

    oder gehört die in deim Verständnis nu auch mit hinein in den MVVM-Pattern?

    Dadurch das die Layer getrennt werden müssen ja, oder wie würdest du es machen? Ich bin ja offen für was einfacheres, aber wie willst du so einfach wie möglich sollche Ding steuern.
    Mit Solche Dinge meine ich, ein einheitliches "System" für Dinge wie Dialoge, Messagenboxen, TaskBarItemInfo, WaitingCursor, usw.
    Da ist DependencyInjection eigendlich noch relativ einfach, da habe ich andere Möglichkeiten auch schon gesehen. Vorallem... es ist 1x implementiert einfach anzuwenden, einfach und schnell zu erweitern und obendrein sogar eben "Cross-Plattform"-Fähig da jede Applikation eben seine eigene Implementierung erstellen kann.

    ErfinderDesRades schrieb:

    Nämlich eine kritische Distanz zu erhalten.

    Ist ja ok, aber wenn ich den Post oben lese wäre die Zusammenfassung: "Wenn man MVVM so genau durchzieht ist das Scheisse, und so eine Scheisse bringt nix weil zu umständlich, da ist es besser man hält sich nicht an das Pattern". Ja, je nachdem was man benötigt. Ich würde niemals für ne kleine App solch einen Aufwand treiben, wenn die Anforderung an eine Applikation oder gar eine Architektur eindeutig keine Trennung der Layer erfordert, dann benötige ich kein MVVM. Das heißt ja nicht das ich keine ViewModel-Klassen haben muss/darf.
    Aber ich betone nochmals: MVVM wird es es ab da wo man das Pattern befolgt, nicht früher. Bis dahin ist es maximal eine Applikation im Stil einer MVVM Anwendung.
    Sicher kannst du jetzt immer wieder bedauern das hier eine gewisse Redundant vorhanden ist und das man bei Gewissen vorhaben einen mehraufwand hat, das ist aber nun mal der Preis den man für die unabhängigkeit der Layer zahlt. Benötige ich es nicht muss ich es nicht machen, mache ich es aber trotzdem, weil wie im Falle der Services nicht wirklich viel Arbeit bin ich dafür bereit, das muss man naber für jedes Projekt entscheiden.

    ICH habe gesagt das ich ein korrektes MVVM Beispiel hochlade, das habe ich gemacht, will es jemand abändern weil er der Meinung ist das dies ein Quentchen zu viel des guten ist, dann gerne, aber bitte nicht behaupten das eine Messagebox im VM noch MVVM ist. Aber vieleicht gibt es ja eine bessere Idee. @ErfinderDesRades Ich habe sehr viele Ansätze gesehen, aber sicher noch nicht alles, vieleicht überrascht du mich ja.

    @Jeiss, ich hoffe ich/wir haben dich nicht verwirrt, und falls es so rüberkahm als das du unbedningt MVVM verwenden sollst tut es mir leid. Gerade ich bin jemand der der Meinung ist das man in der WPF eben NICHT unbedingt MVVM durchziehen muss. Man kann auch gerne an das CodeBehind binden und/oder mit ViewModel ähnlichen Klassen arbeiten. Das ist weder ein Beinbruch nocht finde ich ist es schlechter Stile wenn man dennoch mit Binding arbeitet und nicht die Controls selbst über Code anspricht. Ich hoffe du bist nun nicht ZU verwirrt.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo alle zusammen,
    versuche mal darzustellen wo ich in "dem Ganzen da stehe".

    Nofear23m schrieb:

    Ich hoffe du bist nun nicht ZU verwirrt.

    Doch verwirrt bin ich schon, aber nicht wegen euren "Zankereien" zum Thema MVVM. Gerade wegen eurer unterschiedlichen Ansichten zu dem Thema hab ich jetzt auch eine bessere Vorstellung was "pures" MVVM überhaupt ist. Und eigentlich ist es ja meine "Schuld", dass MVVM in diesem Thread überhaupt ein Thema ist...

    Will man programmieren lernen, das fängt so an: "Hello world"
    Will man mehr über mich wissen, das fängt so an: "Hallo Jeiss" ;)
    Hab vor gut 15 Jahren VBA in Excel kennengelernt, hat mir manches auf meiner Arbeit vereinfacht.
    Irgendwann Windows Forms. Ich hab gelernt Buttons, Labels, TextBoxen, Comboboxen....usw einzusetzen. Ich konnte ihre Eigenschaften im Codebehind verändern. Ich konnte in den Events diese Eigenschaften wieder nach Bedarf, bis zum gewünschten Ergebnis verändern.
    Musste/wollte irgendwann dann auch Daten speichern. Hab mich bei SQL umgekuckt!!! Damals lud man die Daten dann in Datasets. Und da verlor ich die Kontrolle.... Irgendwann kamen nacheinander, VS2005, VS2008, VS2010, VS2013 und Jetzt VS1015. Habe irgendwann dazwischen trotzdem irgendwie gelernt eigene Properties zu erstellen und benutzen. Ab irgendwann "mussten" die Daten statt in ein Dataset, in viel flexiblere Klassen, collections oder Listen. Die konnte man sortieren, filtern, groupieren, konnten nach vorne, nach hinten, zum nächsten.... in alle Richtungen "moven"....
    Richtig "bunt" wurde es dann noch mit WPF und XAML. Da wars vorbei! War eigentlich nur noch in der Lage "Codefragmente" die ich im Internet fand irgendwie Zusammen zu flicken. :(
    Und verwirrt bin ich eigentlich nur darüber, weil ich nicht weiss wie ich den "Anschluss" finden kann.. Es hat irgendwie noch nicht "klick gemacht"!

    So was wünsche ich mir jetzt eigentlich?
    Weil ich ein eher ungeduldiger Mensch bin möchte ich zwei fliegen auf einen Schlag erwischen.
    1. Meine "Programmierkünste" in VB.NET verbessern und 2. irgendwann doch in der Lage sein meine UrgentOrders App zu erstellen.

    Brauche ich "pures" MVVM?
    Ganz klar nein! Mir reicht zu wissen, dass es das gibt und hab jetzt auch irgendwie verstanden wozu das gut ist. Für meine kleinen Apps die ich ab und zu "bastle" reicht mir der Level darunter völlig. Aber die Vorstellung vom "annähernden" MVVM gefällt mir sehr. Ich mag wenn es strukturiert ist. Ich weiss nicht wieviel Zeit ich schon verloren hab weil ich mich in meinem eigenen Code nicht mehr zurecht finden konnte. Da halfen auch keine Regions oder so mehr... Diese Zeit könnte ich viel besser nutzen um wirklich was dazu zu lernen.
    Wenn man im Internet was über ein VB.NET Problem nach schaut, stösst man sehr oft auf MVVM-Vorschläge! Ich hab erst ab Ende Dezember 2017, hauptsächlich dank ErfinderDesRades und Nofear23m, den "Verdacht geschöpft", dass es nicht reicht die View mittels Commands an das ViewModel zu binden um richtig MVVM zu programmieren. Und so kam es, dass ich dachte ich müsste MVVM in diesem Thread erwähnen. Ich wollte halt nur kein Chaos in meiner App haben...und es irgendwie halbwegs richtig machen.
    Heute, am 13. Januar 2018 würde ich sagen, reicht es mir schon wenn mein Programm funktioniert. Einigermaßen "optimiert" von den vielen Möglichkeiten die VB.NET uns bietet gebrauch macht und einen logischen, strukturierten Aufbau zu erkennen ist. Und am meisten freuen würde ich mich wenn ich dann auch noch alles verstehen würde.
    Ok, jetzt wisst ihr wenigstens ein bisschen besser über mich bescheid.
    Aber zurück zum UrgencyPlannerMVVM Projekt. Also ich finde wenn man mir den Code einfach so "vorliest", dann bin ich auch sicher, dass ich ihn richtig verstanden hab. Also ich denk da so eher wenn man es so vorliest:

    ErfinderDesRades schrieb:

    Instance ist nicht mehr und nicht weniger als eine globale Variable.In der gesamten Anwendung, über die gesamte Laufzeit, soll dieses eine Objekt - ServiceContainer.Instance As ServiceContainer unveränderlich abrufbar sein.

    Ok wir erstellen diese ServiceContainer Instanz. Und die verlässt uns nicht mehr bis wir die App schliessen. Gut, ist klar.
    Diese Instanz hat keinen Namen. ok
    Und benutzt wird sie z.B. im "Edit-Command" so:

    VB.NET-Quellcode

    1. Private Sub EditOrderCommand_Execute(obj As Object)
    2. Dim msgServ = Services.ServiceContainer.GetService(Of Services.IMessageboxService)
    3. If _context.ChangeTracker.HasChanges Then
    4. If msgServ.Show("Du solltest zuerst speichern bevor du bearbeitest. Jetzt speichern?", "Arbeit speichern", Services.EnuMessageBoxButton.YesCancel, Services.EnuMessageBoxImage.Question) = Services.EnuMessageBoxResult.Yes Then
    5. SaveCommand.Execute(Nothing)
    6. OpenEditDialog()
    7. End If

    ​Ok damit kann ich für den Augenblick leben, brauch das jetzt nicht genauer zu verstehen. Vielleicht komm ich ja später noch einmal drauf zurück.

    ​So, genug für heute. Diese Service-Geschichte war schon gar nicht so einfach für mich.
    ​Hatte mir noch für heute noch ein Tutorial vorgenommen. Geht glaube ich um Trigger. Bestimmt eine etwas "leichtere Kost".

    ​Ciao,
    ​Bis bald in diesem Thread

    Jeiss schrieb:

    Ok wir erstellen diese ServiceContainer Instanz. Und die verlässt uns nicht mehr bis wir die App schliessen. Gut, ist klar.
    Diese Instanz hat keinen Namen. ok
    Natürlich hat die Instanz einen Namen: Instance - sinnigerweise - steht da doch.

    Den Aufruf, den du danach zeigst - der benutzt die Instanz nicht - deshalb kommt in dem Aufruf der Name auch nicht vor.
    Jetzt wirds schwierig: Die aufgerufene Methode GetService() ist nämlich Shared deklariert (sieh nochmal nach!!), und Du musst nu verstehen, was das Schlüsselwort Shared bedeutet - das ist ganz grundlegendes OOP-Wissen. Guck am besten selbst nach manchmal erklärt Microsoft auch sehr gut: msdn.microsoft.com/de-de/library/dd409611(v=vs.140).aspx
    Hmm - jetzt nochmal geguckt: Gut finde ich die Erklärung nicht. Aber wennde mit klar kommst, wäre's ja fein.
    Oder vlt. hast du ja ein Buch, oder Google sagt dir was verständliches - aber Google ist wirklich die unsicherste Resource in dieser Frage.
    Das Schlüsselwort Shared muss jdfs. unbedingt vollkommen und richtig verstanden sein - sonst kriegt man auf dem Niveau, auf das du los willst, einfach nichts gebacken.
    Andererseits finde ich das nicht soo einfach zu erklären, daher wär mir lieber, du machst dich selbst schlau. Wenns nicht hinhaut, nochmal fragen, dann müssen wir und doch was aus den Fingern saugen.
    Wie gesagt: sowas grundlegendes erkläre ich nur ungern, weil der kleinste Erklärungs-Fehler bleibt bei dir ja für immer stecken - bis du iwann damit auf Nase fällst.
    Oder aber jmd anners hat Lust, es zu erklären versuchen?

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

    Ok, danke.
    shared und den Link von MSDN Knüpfe ich mir also als nächstes vor.
    Ich finde es gut dass du mir eine Richtung angibst, welche "Bausteine" tatsächlich wichtig sind.
    Ist dieser wichtige Baustein noch zu "hoch" für mich, dann weiss ich aber wenigstens wo ich hin soll.
    Klingt vielleicht komisch, aber ich weiss ja selber nicht richtig was ich als nächstes "anpacken" muss.

    EDIT:
    Wir reden ja jetzt gerade über dieses shared, nehme ich mal an?

    VB.NET-Quellcode

    1. Public Shared ReadOnly Instance As New ServiceContainer()

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

    Naja - soo schlecht ist die Msdn-Erklärung auch nicht - ist leider nur eine sehr knappe Definition, und dann reden sie schon von eiglich was annerem (nämlich wann mans benutzen soll). Also die Definietion:
    Specifies that one or more declared programming elements are associated with a class or structure at large, and not with a specific instance of the class or structure.

    Deutsch:
    Shared bestimmt, dass eine oder mehrere deklarierte Programm-Elemente mit einer Klasse [...] als ganzes assoziiert sind, anstatt mit den Instanzen der Klasse [...].
    Nur darüber gilt es zu hirnen, Codebeispiele zu machen, mit und ohne Shared.

    (In diesem Fall ist das "deklarierte Programm-Element" eine als Shared deklarierte Methode. Shared kann sich aber auch auf Felder, Properties und Events beziehen.)



    Edit:

    Wir reden ja jetzt gerade über dieses shared, nehme ich mal an?

    VB.NET-Quellcode

    1. Public Shared ReadOnly Instance As New ServiceContainer()

    Nein, wir reden über

    ErfinderDesRades schrieb:

    Die aufgerufene Methode GetService()
    Ich sagte doch - guck sie dir an.
    An deren Aufruf hast du Anstoss genommen, und gemeint "Instance" habe keinen Namen oder sowas.



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

    Nofear23m schrieb:

    [kritische Distanz...] Ist ja ok, aber wenn ich den Post oben lese wäre die Zusammenfassung: "Wenn man MVVM so genau durchzieht ist das Scheisse, und so eine Scheisse bringt nix weil zu umständlich, da ist es besser man hält sich nicht an das Pattern".
    hmm - das wäre mir nicht so recht, v.a. wg. des Kraftausdrucks, so gelesen zu werden.
    Ich bin eiglich sehr froh über dein Sample - es gibt sicherlich die MVVM-Auffassung der meisten MVVM-Programmierer wieder, und zwar sehr sauber umgesetzt, soweit ich reingeguckt hab. Und funktioniert! - da kriegt man normal ja ganz annere Sachen serviert, wenn man ühaupt mal was bekommt.
    Und vor dem Hintergrund einer vorgesehenen UWP-Anwendung ergibt die Dependency-Injection auch Sinn, und wenn ich mal in Verlegenheit komme, DI einsetzen zu müssen, werde ich genau hier nachgucken :D
    Aber ich melde kritische Distanz in 2 Hinsichten an: Zum einen gibt es durchaus annere Auffassungen von MVVM als die deinige.
    Zum anderen erlaube ich mir darauf hinzuweisen, dass MVVM - insbesondere in deiner Ausführung - teilweise im Widerspruch zu anderen wichtigen Programmierprinzipien steht, etwa YAGNI und DRY.
    Ich sehe den Konflikt MVVM - YAGNI/DRY als ein Spannungsfeld, das MVVM-Programmierer (der am weitesten verbreiteten Auffassung davon) halt aushalten müssen.

    ErfinderDesRades schrieb:

    Zum einen gibt es durchaus annere Auffassungen von MVVM als die deinige.

    Kannst du das konkretisieren? Meiner Meinung nach ist der wichtigste Leitfaden das die Layer voneinander getrennt sind. Häng dich jetzt bitte nicht an dem UWP Beispiel auf, das kann ja mehrere Gründe haben.
    Beispielsweise kann es sein das der Kunde meint: "Wir möchten das die View später mal getauscht werden kann" oder gehen wir einen Schritt weiter. Wenn der Kunde meint er wollte das im Moment direkt auf die DB zugregriffen werden soll, später aber soll mal ein Webservice erstellt werden und dann müssen alle Anwendungen dieses um Daten bemühen. Dann wird man die Applikation sicherlich in Layern mit einem DataAccessLayer dazwischen aufbauen, wo einem ein sollches MVVM Konzept sicherlich Hilft. Es gibt einige Einsatzscenarien. Ein sehr wichtiger Punkt für viele ist z.b. das mit der Layertrennung alle Layer Testbar sind. Klar, MVVM wird immer ein wenig mit der Aussage "Da können dann Designer und Programmierer unabhängig Arbeiten" in verbindung gebracht.
    Kann ich bestätigen, mache ich seit nem Jahr in einem Projekt so und das klappt super, ICH muss von Design nix wissen und der Designer muss von Code nix wissen. Somit gibt es auch keine Konflikte in der Quellcodeverwaltung.
    ABER! Andere Auffassung, naja. Ich sehe den Begriff M - V - VM vieleicht nicht ganz so dehnbar wie andere, Layertrennung ist Layertrennung, und dann darf ich eben im VM Layer nix mit einem VIew machen. Und z.b. ne Messagebox gehlrt zum View.

    ErfinderDesRades schrieb:

    Zum anderen erlaube ich mir darauf hinzuweisen, dass MVVM - insbesondere in deiner Ausführung - teilweise im Widerspruch zu anderen wichtigen Programmierprinzipien steht, etwa YAGNI und DRY.

    Ich denke nicht das es im Wiederspruch steht, zumindest dann wenn man MVVM nur dann Anwendet wenn es gebraucht wird, und genau da liegt der Hase im Pfeffer !!!!!!
    In Foren (auch hier) liest man immer wieder das den Leuten dazu geraten wird MVVM zu verwenden sobald mit der WPF gearbeitet wird. Was ja nicht korrekt ist.
    Sobald ich das Wort MVVM in den Mund nehme muss ich mir im klaren darüber sein was MVVM genau ist und was es für den Programmierer und den Programmieraufwand bedeutet!! Nämlich einen enormen mehraufwand, und das ist es was du mit dem Konflikt meinst, nur steht es erst dann im Konflikt wenn ich MVVM nachgehe ohne es zu brauchen. Und da sind wir nun angekommen. Brauchen wir es oder nicht?
    Und hier bin ich persönlich der Meinung das sicher 80% der Applikationen welche in MVVM oder einem MVVM - Ähnlichem konstrukt Aufgebaut werden dieses nicht benötigen.

    Und jetzt gehts los, warum rät dann jeder zu MVVM?
    Tja, weil die meissten entweder nachplappern was sie hören oder nicht genau wissen was MVVM ist oder es noch nie versucht habe korrekt(!!) umzusetzen und somit auch nicht wissen was dies für einen Aufwand bedeutet.
    Wenn du nochmal in mein Inhaltsverzeichnis meines Tuts siehst findest du Hinweise darauf das ich nahe bringen möchte das man in der WPF ganz ohne MVVM auch alle Vorteile von DataPicking, DesignTimeSupport usw haben kann ohne auch nur annähernd MVVM zu Betreiben.

    Last but not least
    MVVM hat seine Berechtigung, man muss allerdings sehr gut darüber nachdenken ob man es braucht.
    Einmahl alles wichtige im Kern (ich nenne es gerne Kern) implementiert läuft es dann eh und man hat in weiterer Folge keinen Mehraufwand, aber dieser Kern muss mal sauber erstellt werden und das dauert auch mal länger.
    Dafür erhält man ein saubere und Strukturierte Anwendung welche Testbar, einfach wartbar und vorallem und das ich MIR wichtig SKALIERBAR ist.

    Ich weis, mit dem Wort skalierbar (ich hatte es bis jetzt vermieden) breche ich jetzt vieleicht Diskussionen von Zaun aber ich finde es ist ein wichtiger Punkt. Wie oft war es der Fall das man eine Anwendung erstellt hat welche nach einiger Zeit vermutlich das doppelte konnte als zum ersten Release. Chef: "Lauft gut jetzt könnten wir ja gleich noch das und das und das und das einbauen, wäre doch super."
    Tja, die Anwendung war nicht dafür aufgebaut und man hatte so viel mehraufwand das man die App gleich tirichtig aufbauen hätte können.

    Fazit
    Ich gebe dir Recht das man wirklich nur so viel machen sollte wie man benötigt, hier gehe ich konform mit YAGNI, aber die große frage ist ja "was wird benötigt".
    Und das wissen die wenigsten überhaupt selbst!!! Da ist es dann meisst besser höher anzusetzen als zu tief, aber nicht ZU hoch.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo ErfinderDesRades,
    Wir reden ganz leicht aneinander vorbei. Ist aber gar nicht schlimm, denn du hast mir trotzdem geholfen mein Problem mit diesem Service besser zu verstehen.
    Die Bedeutung von Shared war der Schlüssel zum Ganzen.
    Ich bin nämlich tatsächlich schon viel früher "angeeckt". Und zwar tatsächlich im Application StartUp.
    Da steht nämlich:

    VB.NET-Quellcode

    1. ServiceInjector.InjectServices()

    Und InjectServices ist eine shared Methode
    Was ich damit meinte als ich schrieb die Instanz habe keinen Namen, war der shared "Aufruf" von Instance der Klasse ServiceContainer
    Also mit dem besseren Verständnis der Bedeutung von Shared ist schon vieles klarer geworden. Danke!

    Ich will die Antwort jetzt eigentlich gar nicht wissen, ich finde ich weiß vorläufig mal genug über diese Services um mich dem nächstem Problem zu widmen.
    Aber ich finde folgendes irgendwie "interessant"..
    Eine Klasse darf ja nicht shared sein, nur ihre "Member", oder?
    Aber in der Klasse ServiceContainer machen wir (genauer gesagt macht Sascha... :) ​) folgendes:

    VB.NET-Quellcode

    1. ​Public Shared ReadOnly Instance As New ServiceContainer()

    Das bedeutet doch irgendwie, dass die Instanz ​Instance die ja für die Klasse ​ServiceContainer steht, doch shared ist... bin ich mir jetzt aber nicht mehr so sicher ob ich das mit Shared gerafft hab?

    Jeiss schrieb:

    ich finde ich weiß vorläufig mal genug über diese Services

    Eigendlich geht es bei den Services (ist nur eine bezeichnung von mir in diesem Fall, Services ist jetzt keine Technik oder sonstwas, nur meine Bezeichnung) ja um DepenencyInjection.

    Das ich das mit solch einer Klasse mache ist ein anderes Thema (was auch interessant ist wie du ja gerade merkst) weil es das ganze sehr einfach macht (in der endgültigen Anwendung).

    Es geht bei diesem "Service" im Grunde um DependencyInjection und das ist ein Kaptiel für sich.

    Aber ich finde gut das du versuchst es zu verstehen. Mach dich aber bitte nicht selbst fertig wenn du nicht ALLES und JEDE Zeile genau verstehst.
    Ein Mechaniker weis auch wie ein Getriebe funktioniert und kann es auch Reparieren wenn es einen Defekt hat, das heißt aber nicht das er eines bauen könnte. Hoffe den Satz bekommt jetzt niemand in den falschen Hals.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Jeiss schrieb:

    Eine Klasse darf ja nicht shared sein, nur ihre "Member", oder?
    Aber in der Klasse ServiceContainer machen wir (genauer gesagt macht Sascha... :) ) folgendes:

    VB.NET-Quellcode

    1. Public Shared ReadOnly Instance As New ServiceContainer()

    Das bedeutet doch irgendwie, dass die Instanz Instance die ja für die Klasse ServiceContainer steht, doch shared ist... bin ich mir jetzt aber nicht mehr so sicher ob ich das mit Shared gerafft hab?
    Eine Klasse kann in VB nicht Shared sein.
    Klassen-Member können Shared sein - müssen aber nicht; standardmässig sind KlassenMember Objekt-Member, nicht Shared, Instanzen-Member, oder wie mans ausdrücken will.

    Jeiss schrieb:

    Das bedeutet doch irgendwie, dass die Instanz Instance die ja für die Klasse ServiceContainer steht, doch shared ist... bin ich mir jetzt aber nicht mehr so sicher ob ich das mit Shared gerafft hab?
    Das bedeutet genau was da steht: Instance ist ein Shared Member der Klasse ServiceContainer.
    Instance "steht nicht für" die Klasse ServiceContainer - ich wüsste garnet, was du mit "stehen für [Klasse]" überhaupt meinst.
    Nochmal: Instance ist ein Public Shared Readonly Member der Klasse ServiceContainer - nicht mehr und nicht weniger, und das steht da ja auch.
    Wenn man dessen Bedeutung betrachtet, die habich bereits in Post#98 genannt: Es "bedeutet", dass Instance eine readonly globale Variable ist - überall im Projekt zugreifbar, und auch von allen Projekten, die auf dieses verweisen.
    Hallo alle zusammen,
    bin gerade dabei den context in diesem schönen Beispiel zu studieren (oder besser gesagt zu versuchen ihn zu verstehen)
    Kann mir jemand dabei helfen alles hier richtig zuzuordnen?
    Also auf eine für mich noch nicht nachvollziehbare Weise (muss sich wohl irgendwie um ein durch Code-first erstelltes Entity-Model handeln) ist hier ein "Entity-Modell" erstellt worden. Soweit ich der App.config Datei entnehmen kann bezieht es die Daten aus der ordersDb.mdf Datei. Und soweit ich das verstehen kann bekommt dieses "Model" ihren Namen auch in der App.config, und zwar mit name="OrdersContext" zugewiesen. Oder?
    Sascha hat also die "Public Class OrdersDbContext" angelegt.

    VB.NET-Quellcode

    1. Public Class OrdersDbContext
    2. Inherits DbContext
    3. ....
    4. Public Sub New()
    5. MyBase.New("OrdersContext")
    6. ....

    Wo OrdersDbContext von DbContext erbt.
    ​Laut ObjektBrowser ist die "Public Class DbContext" ein "Member of System.Data.Entity​" ist. Ok wird uns also irgendwie zur Verfügung gestellt....
    ​Dem Constructor von DbContext (MyBase) wird der String "OrdersContext" übergeben. Was passiert hier? Ich nehm mal an, dass man der Klasse DbContext über "den ConnectionString" aus der App.config den Weg zu den Daten angibt....
    ​Und wenn die Daten dann angezeigt werden sollen, werden sie im "UrgencyListVM" über die Prozedur "LoadData" der View zur Verfügung gestellt.

    VB.NET-Quellcode

    1. ​Private Sub LoadData()
    2. _context = New OrdersContext.OrdersDbContext
    3. ​....


    Kann man das so, als "vereinfachte Vorstellung der Abläufe" (für mich), so gelten lassen. Oder wickelt das sich total anders ab?
    ​Ich würde mich zu diesem Zeitpunkt noch mit einem "vereinfachten" Model des Daten Kontextes begnügen.
    Ich möchte mich jetzt nicht auch noch mit dem Studium des Entity Models "belasten", hab wirklich schon genug mit diesem "grossen" Beispiel zu kämpfen.

    Jeiss schrieb:

    Also auf eine für mich noch nicht nachvollziehbare Weise (muss sich wohl irgendwie um ein durch Code-first erstelltes Entity-Model handeln) ist hier ein "Entity-Modell" erstellt worden.

    Ist keine Magie. Du erstellst das Model wie folgt.

    Eine Klasse stellt eine Tabelle in der DB dar. Public Class Auto
    Ein Property in der Klasse stellt eine Spalte in der DB dar. Public Property Marke as String und der Datentyp dabei den Datentyp der Spalte in der DB, hier String

    Im Context hast du dann Public Overridable Autos as DBSet(Of Auto).
    EF weis damit: OK, Ich muss eine Tabelle mit dem Namen 'Autos' anlegen und eine Spalte mit dem Namen 'Marke' und dem Datentyp varChar.
    Hast du z.b. noch eine Tabelle Modelle und in der Auto-Klasse dann Public FahrzeugModell as Modell und in der Klasse Modell ein Property Public Autos as List(Of Autos) weis EF somit das es eine 1:N Beziehung herstellen muss, denn ein Auto kann einem Modell zugeordnet sein aber ein Modell kann vielen Autos zugeordnet sein.

    Eigendlich ja ziemlich intuitiv wie ich finde.

    Jeiss schrieb:

    Soweit ich der App.config Datei entnehmen kann bezieht es die Daten aus der ordersDb.mdf Datei. Und soweit ich das verstehen kann bekommt dieses "Model" ihren Namen auch in der App.config, und zwar mit name="OrdersContext" zugewiesen. Oder?

    Nein, das Model hat so gesehen keinen Namen. Der Name ist wie oben beschrieben damit EF weis wo es den ConnectionString her bekommt.
    In der App.config steht nur der ConnectionString drinnen.

    Jeiss schrieb:

    Wo OrdersDbContext von DbContext erbt.
    ​Laut ObjektBrowser ist die "Public Class DbContext" ein "Member of System.Data.Entity​" ist. Ok wird uns also irgendwie zur Verfügung gestellt....

    DbContext ist eine Klasse vom EntityFramework. Du erbst von dieser Klasse um dann die DBset`s (im Enteffekt deine Tabellen) in den Context zu bringen.
    Diese Klasse ist etwas was dir beim ModelFirst Ansatz automatisiert durch das T4 Template generiert wird. m CodeFirst schreibst du diese quasi selbst, viel ist ja nicht drinnen.

    Jeiss schrieb:

    Dem Constructor von DbContext (MyBase) wird der String "OrdersContext" übergeben. Was passiert hier? Ich nehm mal an, dass man der Klasse DbContext über "den ConnectionString" aus der App.config den Weg zu den Daten angibt....

    Wenn du in die app.config siehst dann hast du dort den ConnectionString. Dieser ist über das "Name" Attribut benannt worden. Genau diesen Namen übergibst du damit EF weis welchen ConnectionString es sich holen soll, denn es könnte ja mehrere Contexte geben und sohin auch merhere Connectionstrings.

    Jeiss schrieb:

    Kann man das so, als "vereinfachte Vorstellung der Abläufe" (für mich), so gelten lassen. Oder wickelt das sich total anders ab?
    ​Ich würde mich zu diesem Zeitpunkt noch mit einem "vereinfachten" Model des Daten Kontextes begnügen.
    Ich möchte mich jetzt nicht auch noch mit dem Studium des Entity Models "belasten", hab wirklich schon genug mit diesem "grossen" Beispiel zu kämpfen.


    Im Grunde ja, Beim Abrufen von Daten gelten hald eben noch viele, viele andere Regeln und kniffe sowie dann noch das ChangeTracking, Migration usw.
    Entity Framework füllt ganze Bücher von denen ich bereits 3 hier liegen habe, aber um die Grundlegene Funktionsweise zu verstehen bedarf es eigendlich nicht viel.

    Aber Achtung:
    1. Ich habe ein CodeFirst Beispiel erstellt nicht so wie du ein ModelFirst (weil ich das lieber habe und es in Zukunft keinen anderen Ansatz mehr geben wird (ausser durch Tools von dritten))
    2. Sind hier nur die Grundlegenden Funtionen des EF demonstriert worden (Beispiel siehe unten)
    3. Hat das EF jetzt nicht wirklich was mit einem MVVM zu tun, das war wirklcih nur für "dein" Beispiel mit drinnen. Mach dich nicht fertig deshalb wenn du EF vieleicht gar nicht brauchst.

    Hier ein Beispiel wie ICH die Abfrage:

    VB.NET-Quellcode

    1. Dim ordersList = (From u As Order In _context.Orders.Include(Function(u) u.Answers).Include(Function(wc) wc.CurrentWorkCenter)).ToList

    Wohl eher Definieren würde (alleine schon aus Performancegründen und weil die Abfrage ja eigendlich gar nicht korrekt ist)

    VB.NET-Quellcode

    1. Dim ordersQuery = (From u As Order In _context.Orders.Include(Function(u) u.Answers).Include(Function(wc) wc.CurrentWorkCenter)) 'Includiert Tabellen (Joins)
    2. ordersQuery = ordersQuery.Where(Function(o) o.DeletedFlag = False) 'Nur nicht gelöscht selektieren (also 'als gelöscht' markiert Filtern)
    3. ordersQuery = ordersQuery.OrderBy(Function(o) o.CreationTimestamp).ThenBy(Function(o) o.OrderNr)
    4. 'Abzurunfende Spalten beschränken
    5. ordersQuery = ordersQuery.Select(Function(o) New Order() With {.ArticleNr = o.ArticleNr, .ConfirmationDate = o.ConfirmationDate, .CreationTimestamp = o.CreationTimestamp, _
    6. .Description = o.Description, .OrderNr = o.OrderNr, .Quantity = o.Quantity,.CurrentWorkCenter = o.CurrentWorkCenter, .Answers = o.Answers.Select(Function(a) New Answer() With _
    7. {.AnswerText = a.AnswerText, .ContactName = a.ContactName, .RequestDate = a.RequestDate}).ToArray}).AsQueryable
    8. Dim ordersList As List(Of Order) = ordersQuery.ToList 'Hier wird die Abfrage eigendlich erst ausgeführt und die DB darum bemüht


    Da wird zum einen mal auf nur 'nicht gelöschte' selektiert, und dann noch sortiert und zum anderen wird EF wegen dem 'Select' nur die angegebenen Spalten abrufen.
    Das spart Zeit, entlastet den SQL Server und du hast weniger Daten im RAM.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo ErfinderDesRades,
    Ok, dann hab ich das mit dem Kontext doch irgendwie verstanden. 8o
    Aber trotzdem verwechsle ich da noch was...ja klar Kontext-Objekt, das sind noch nicht die eigentlichen Daten die geladen/angezeigt werden.
    Der ganze "Load-Vorgang" sieht in diesem Beispiel so aus:

    VB.NET-Quellcode

    1. Private Sub LoadData()
    2. _context = New OrdersContext.OrdersDbContext
    3. _aviableWorkCenters = _context.WorkCenters.Where(Function(wc) wc.DeletedFlag = False).ToList
    4. Dim ordersList = (From u As Order In _context.Orders.Include(Function(u) u.Answers).Include(Function(wc) wc.CurrentWorkCenter)).ToList
    5. UrgentOrderList = New ObservableCollection(Of UrgentOrderVm)
    6. For Each order In ordersList
    7. UrgentOrderList.Add(New UrgentOrderVm(order, _aviableWorkCenters))
    8. Next
    9. UrgentOrdersView = CollectionViewSource.GetDefaultView(UrgentOrderList)
    10. UrgentOrdersView.Filter = AddressOf FilterOrders
    11. UrgentOrdersView.MoveCurrentToFirst() 'Ersten Datensatz mal markieren
    12. _statusBarVm.LastReloadDateTime = DateTime.Now
    13. End Sub

    Also ab _aviableWorkCenters (Private _aviableWorkCenters As List(Of WorkCenter)) reden wir aber von Daten, oder?
    ​Ok, wenn das also so ist, dann schliess ich das Thema "Entity und Datacontext" einstweilen mal. Genauer brauch ich das jetzt nicht zu wissen.
    ​Vor allem da Entitymodel ja ein "Thema für sich ist", und kein leichtes/kleines...
    ​Mal sehen wo ich als nächstes "stecken bleib".

    Danke,
    ​Jeiss
    naja, überall, wo vom _context was abgerufen wird reden wir von Daten, konkret: Zeilen #3 - #4
    Die Zeilen #5-#8 convertieren dann die List(Of Order) in eine ObservableCollection(Of UrgentOrderVm) - unter Hinzuziehung der List(of WorkCenters).
    Danach folgen Einstellungen/Eingriffe am Viewmodel - also das gelangt über Bindings dann zur Anzeige.

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

    Und da gebe ich mir solche mühe mit meiner Antwort ;(
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo Sascha,
    ist schon gut, dass du dir "solch eine Mühe" gibst, ich will ja so viel wie möglich "davon tragen".
    Bin zwar schon recht müde, will mir die heutigen Antworten morgen nochmal genauer angucken.
    Aber trotzdem noch eine Frage?

    Nofear23m schrieb:

    Hast du z.b. noch eine Tabelle Modelle und in der Auto-Klasse dann Public FahrzeugModell as Modell und in der Klasse Modell ein Property Public Autos as List(Of Autos) weis EF somit das es eine 1:N Beziehung herstellen muss, denn ein Auto kann einem Modell zugeordnet sein aber ein Modell kann vielen Autos zugeordnet sein.

    In deinem/unserem/aktuellen Beispiel mit den Klassen Order und Answer wäre es ja wohl das..?
    Im "Model", Public Class Order (Parent Tabelle)

    VB.NET-Quellcode

    1. Public Overridable Property Answers As [b]ICollection[/b](Of Answer)
    um die 1:n Beziehung herzustellen?
    Statt wie du mit den "Autos" erklärt hast: Public Autos as [b]List[/b](Of Autos) in der Klasse "Modell".
    ​Aber wie gesagt, bin müde. Les das morgen noch einmal durch.
    ​Fang an Autos, answers, orders und Modelle durcheinander zu schmeißen...
    ​Gute Nacht.
    Ja. Auch wenn du müde bist hast du das genau richtig interpretiert.
    Deshalb habe ich es mit Autos gemacht, so kann man schön sehen ob du es um-denken kannst. Und es passt. Richtig erkannt.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##