Bindung nach Entity Model first aktualisiert Daten nicht!

  • WPF

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

    Bindung nach Entity Model first aktualisiert Daten nicht!

    Hallo melde mich mal wieder mit einem neuen Problem.
    Hab versucht nach dem Prinzip vom Entity-Model First eine Datenbank für mein Projekt zu erstellen. Abgekuckt hab ich hier.
    msdn.microsoft.com/en-us/library/jj205424(v=vs.113).aspx
    (Geb den Link einfach so ein. Hat mit dem Link-button irgendwie nicht geklappt.)
    Die .MDF Datei wurde auch erstellt, laut Server Explorer hat sie auch 2 Tabellen. (Soll eine 1/n Relation sein)
    Im MainWindow sollen zwei DataGrids, über eine CollectionViewSource an die Daten gebunden werden.
    Die Grids zeigen auch die richtigen Spalten an (an den Bezeichnungen in den "Headern" der leeren Spalten zu erkennen)
    Startet man das Projekt, dann werden leere Datagrids angezeigt. Ist ja auch kein Wunder da die Tabellen in der "fuschneuen" .MDF ja noch keine Daten enthalten.
    Gebe ich Werte in die Grids ein sieht auch noch alles ziemlich normal aus. Außer, dass die ID-Nummern immer auf "0" stehen bleiben. (wenn ich mehrere Zeilen im "Haupt-Grid" mit Daten fülle)
    Aber obwohl überall für die ID-Nummern Nullen eingetragen sind, reagiert das Grid mit den "Child-Daten" wenn ich im "Parent-Grid" in eine andere Zeile klicke.??
    Ja und dann das aller frustrierenste natürlich. Wenn ich das Projekt dann stoppe und neu starte sind natürlich gar keine Daten mehr da...
    Und meine Frage ist natürlich jetzt, gibt es eine Möglichkeit hier im Forum ein solches Problem, das ja das ganze Projekt betrifft, zu behandeln?
    Da gibt es ja so viele mögliche Ursachen die zu diesem "Verhalten" meines Projekts führen könnten.
    Ach ja, Fehlermeldungen hab ich keine!!!
    Weiss jemand wie man bei so einem Problem vorgehen sollte um den/die Fehler zu finden.

    Danke im Voraus,
    Jeiss
    Hallo

    Da du Model-First machst gehe ich mal davon aus das du mit dem Entity Framework 6 arbeitest. Dieses ist ja fast schon veraltet, man sollte das EF Core nehmen, ist aber natürlich kein muss.
    Kannst ja auch beim 6.x bleiben. Ab Core wird offiziell auch nur noch Code-First unterstützt, was sowieso besser ist.

    Jeiss schrieb:

    Aber obwohl überall für die ID-Nummern Nullen eingetragen sind, reagiert das Grid mit den "Child-Daten" wenn ich im "Parent-Grid" in eine andere Zeile klicke.??

    Das passt. Du hast ja die Relation, EF kann die verbindung herstellen ohne das die ID`s vorhanden sein müssen da die RelationProperties vorhanden sind. Id`s hast du ja erst sobald du mal speicherst da diese von der Relationellen DB erzeugt werden.

    Jeiss schrieb:

    Ja und dann das aller frustrierenste natürlich. Wenn ich das Projekt dann stoppe und neu starte sind natürlich gar keine Daten mehr da...

    Was auch klar ist wenn du nicht SaveChanges des DB Context`s aufrufst.

    Seh dir mal die Basics bez. Entity Framework an und wenn du fragen hast stell bitte ein wenig Code auch mit ein.
    Hier und dann auch EF 6.
    Wir sehen hier weder dein Model, noch den Context und/oder wie du Bindest.
    Ich habe jetzt alles nur geraten bzw. gehe jetzt mal von den typischen Anfangsfehlern aus.

    Achja, mit EF kannst du unter WPF nicht direkt arbeiten!!!!
    Die Properties der Klassen (gerade bei Model-First) welche dir generiert werden enthalten kein "OnNotifyPropertyChanged". Du kannst also nicht korrekt binden.
    OK, man kann das T4 Template anpassen aber das ist eher unschön!!
    Ich empfehle ein ViewModel zu erstellen welches die jeweilige Entität bearbeitet und syncronisiert. Weitere Infos kann ich gerne auf nachfrage geben.

    Wenn du unter WPF mit dem EF arbeitest gibt es einiges zu beachten wenn du nicht dauernd stolpern willst. Und falls du MVVM arbeitest musst du ja sowieso auf ein RepositoryPattern setzen.



    Grüße
    Sascha

    Jeiss schrieb:

    Und meine Frage ist natürlich jetzt, gibt es eine Möglichkeit hier im Forum ein solches Problem, das ja das ganze Projekt betrifft, zu behandeln?

    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,
    ja sowas in der Art. Denk schon dass es das ist was du meinst.
    Ich zeig dir mal am Besten meinen ganzen Code-Behind.
    Es ist nicht viel, bin ja nicht weit gekommen. :(

    VB.NET-Quellcode

    1. ​Class MainWindow
    2. Public UrgentOrdersViewSource As System.Windows.Data.CollectionViewSource
    3. Public UrgentOrdersData As ObservableCollection(Of UrgentOrder)
    4. Public _context As UrgentOrderContext '= New UrgentOrderContext()
    5. Public NewUrgentOrder As UrgentOrderContext
    6. Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    7. UrgentOrdersViewSource = CType(Me.FindResource("UrgentOrdersViewSource"), CollectionViewSource)
    8. _context = New UrgentOrderContext()
    9. UrgentOrdersData = New ObservableCollection(Of UrgentOrder)(From items In _context.UrgentOrderSet)' Where items.OrderNbr Is Nothing)
    10. UrgentOrdersViewSource.Source = UrgentOrdersData '.ToList
    11. End Sub
    12. Private Sub btnSave_Click(sender As Object, e As RoutedEventArgs) Handles btnSave.Click
    13. Me._context.SaveChanges()
    14. 'Me.Close()
    15. End Sub
    16. End Class


    ​Ist es das ​Me._context.SaveChanges() was du meinst?

    Danke,
    Jeiss
    Hallo

    Ja, genau. Bedenke das SaveChanges Integer zurückgibt. Du kannst also prüfen wieviele Datensätze von der speicherung betroffen waren. Dies ist immer gut zum prüfen. Gibt SaveChanged 0 zurück hat der Context keine änderung eines Datensatzes mitbekommen. z.b. weil du mit .AsNoTracking abgerufen hast.

    Klappt es denn nun mit dem speichern?

    PS: Vergiss nicht den Context wieder zu Disposen!!!!

    Achja:
    Besser statt:

    VB.NET-Quellcode

    1. UrgentOrdersData = New ObservableCollection(Of UrgentOrder)(From items In _context.UrgentOrderSet)

    mach:

    VB.NET-Quellcode

    1. UrgentOrdersData = New ObservableCollection(Of UrgentOrder)(From items In _context.UrgentOrderSet).ToList


    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 Sacha,
    nein das mit dem speichern will trotzdem nicht.

    Bedenke das SaveChanges Integer zurückgibt.


    Du wie les ich den Wert von SaveChanged() denn aus.

    Hänge ich ein .ToList an, dann krieg ich folgenden Fehler:
    Value of type 'List(Of UrgentOrder)' cannot be converted to 'ObservableCollection(Of UrgentOrder)'

    Update:
    ​Mir ist erst jetzt aufgefallen, dass meine ObservableCollection die mit dem Namen "UrgentOrdersData​" dien neuen einträge auch im Code-Behind enthält. Ihre Count Eigenschaft ist z.B. 2 wenn ich 2 neue Einträge in den Grid eingegeben hab. Ich kann ja nicht mehr so weit davon entfernt sein. Der Context muss es nur noch mitbekommen dass da neue Daten sind....

    ​Hab jetzt leider keine Zeit mehr für mehr Code und so. Hol das später im Nachmittag nach.

    Danke,
    Jeiss

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

    Nofear23m schrieb:

    Achja, mit EF kannst du unter WPF nicht direkt arbeiten!!!!

    Sorry, habs nur aus dem Kopf geschrieben.
    Evtl. dann so: UrgentOrdersData = New ObservableCollection(Of UrgentOrder)((From items In _context.UrgentOrderSet).ToList)

    Du wie les ich den Wert von SaveChanged() denn aus.

    z.b.

    VB.NET-Quellcode

    1. dim ret as integer = _context.SaveChanges
    2. Messagebox.show(ret)

    Aber der Context bringt auch einen ChangeTracker mit sich, welchen man auch befragen kann.
    Wie gesagt, EF ist sehr umfangreich und füllt ganze Bücher, ich selbst habe drei zuhause. Sich hier nicht mit den ganzen Basics zu beschäftigen bricht einem früher oder später das Kreuzt.
    Wichtig ist, erstmal zu verstehen wie EF funktioniert.

    Das problem was du haben wird ist folgendes sein: Du machst aus einer List(Of) welche dir das EF zurückgibt eine ObservableCollection, bekommst also ein neues Objekt. Dieses Objekt bearbeitest du.
    Da der DB-Context diese bearbeitung nich mitbekommt, weis er auch nicht das sich etwas geändert hat. Genau müsste ich es mir anhand eines Beispiels ansehen, ich habe schon länger nicht mehr direkt mit EF gearbeitet sondern nur über MVVM mit einem generischem Repository, das arbeitet ein wenig anders. Ausserdem arbeite ich nur noch mit EF Core.

    Du kannst ja gerne ein Beispiel (ein sauberes Testprojekt) hochladen und ich schau mir das mal an. Aber wie gesagt, normalerweise Arbeitet man auf keinem Fall DIREKT mit den Models sondern bindet nur auf ViewModels (oder Hilfsklassen, wie man es sehen will) und manipuliert über diese den Context. Das ist nicht nur viel sauberer sondern auch viel verständlicher.

    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. ##

    Hi Sacha,
    hiermit bestätige ich, dass _context.SaveChanges den Wert "0" zurück gibt!
    Den ChangeTracker hatte ich auch entdeckt, kann ihm aber nichts nützliche entnehmen.

    Was meinst du mit:
    Gibt SaveChanged 0 zurück hat der Context keine änderung eines Datensatzes mitbekommen. z.b. weil du mit .AsNoTracking abgerufen hast.

    Was oder Wer kann mit .AsNoTracking abgerufen werden? Wo kann diese Eigenschaft gesetzt, bzw. geändert werden?

    Ich frag mich ob ich das ganze nicht neu anfangen soll.... Anders rum. Hab schon soviel Zeit mit diesen paar Code-Zeilen verloren.
    Aber vielleicht gerade deswegen sollte ich meinem Projekt eine letzte Chance geben und das gezipte Projekt mal hochladen, dass jemand sich das angucken kann.

    Aber was meinst du mit:
    Du kannst ja gerne ein Beispiel (ein sauberes Testprojekt) hochladen

    Was ist bitte ein "sauberes Testprojekt"?

    Danke,
    Jeiss

    Jeiss schrieb:

    Was ist bitte ein "sauberes Testprojekt"?
    na eines, was man entpacken und starten kann, ohne zig Abhängigkeiten recherchieren und nachführen zu müssen, oder Daten erstmal ranschaffen etc.
    Das ist garnet so einfach zu fabrizieren - bitte als erstes selber testen, ob der zip geht in diesem Sinne.

    eine andere Bedeutung von "sauber" ist, dass keine ausführbaren Dateien enthalten sein sollen.



    Ob du dein Projekt neu anfangen solltest ist schwer zu sagen.

    Meine Wenigkeit ist nach diesem Thread hier nochmal wieder regelrecht abgestoßen von diese dolle EF-Core, EF6, CodeFirst. Was alles nach 2 Jahren wieder outdated ist, und wo man trotz Gigabyte-Schwerer Bibliotheken am Ende garnix mit anfangen kann, ausser alles umfüllen in nochmal ein Viewmodel, damit auch jeder Sch... mindestens dreimal programmiert wurde,...
    Das Prinzip "Dont repeat yourself" scheint ja inne Wpf-Datenbänkerei nicht mehr zu gelten.
    :cursing:

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

    Hallo,
    ​ok das ist also Sauber.... ganz klas ist es mir immer noch nicht!
    ​Ich hab ja bloss so ein, wie sich ers jetzt heraustellt, kompliziertes Projekt angefangen, weil es mir darum ging eine Datenbank zu erzeugen/erstellen.
    ​Und gerade die wurde auf meiner Festplatte in den "Dokumenten" abgelegt, konnte ich mir nicht aussuchen. Das Projekt enthält ja verweise an diese .mdf Datei. (allein schon in der App.config)
    ​Muss die Mdf auch irgendwie mit gezippt werden, z.b. in der Projektdatei?

    Danke,
    Jeiss
    @ErfinderDesRades Willkommen in der Gegenwart ;)

    Du hast ja für EF auch einen Designer. Da kann man seine Entitäten samt Relationen einfach im Designer erstellen.
    Daraus wird sowohl der C# Code für die Model und DBContext KLassen generiert, als auch SQL Scripts zum erstellen der Datenbank.
    Das heißt du hast also dein komplettes Model schon fertig ohne eine Zeile Code.

    Ob du dann das Respository und UnitOfWork Pattern verwendest bleibt dir überlassen.
    MVVM mit WPF ist ja im Grunde sowieso schon Standard. Dh du programmierst eigentlich in erster Linie in deinen ViewModels und verwendest das Datenmodell generiert durch die T4 Templates.
    Was du nun dahinter hast macht doch kaum einen Unterschied?
    Verstehe nicht wieso das 3 mal das selbe Programmieren ist?
    Das ist meine Signatur und sie wird wunderbar sein!
    von welchem EF sprichst du? Core? EF6? Edmx-Klassen? Codefirst?
    Bei Codefirst - gibts da den von dir genannten Designer?

    Und ich bezog mich auf NoFear, der sich von T4 recht unbegeistert zeigt.
    Und der T4-Kram - funktioniert das bei dir? Worauf habt ihr aufgebaut, und wie lange habt ihr gebraucht, es auf eure Bedürfnisse anzupassen?
    Und ists stabil?
    Da schreibt sich doch auch jeder sein eigenes, alles mit Vor- und Nach-teilen und jedes höchst gewöhnungsbedürftig.
    Und am Ende kann man damit immer noch keine konsistente m:n-Relation anzeigen, und die Change-Trackerei fällt auch dem Feature-Cutting zum Opfer, weils nämlich beim Umfüllen von Model->Viewmodel und zurück kaum möglich ist, die Changes (inklusive Löschungen) konsistent zu transferieren.

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

    Kann da nicht mit reden,
    ​da es ja aber auch ein wenig um mein Problem geht ;) ​ wollte ich betonen, dass ich genau so vorgegangen bin wie Mono es so gut beschrieben hat.
    ​und zwar mit dem EF-Designer aber mit Model-firs, klang ganz vielversprechend. Hatte vergessen das zu erwähnen.

    So, Film zu ende, hab wieder Zeit 8o

    ErfinderDesRades schrieb:

    Meine Wenigkeit ist nach diesem Thread hier nochmal wieder regelrecht abgestoßen von diese dolle EF-Core, EF6, CodeFirst. Was alles nach 2 Jahren wieder outdated ist, und wo man trotz Gigabyte-Schwerer Bibliotheken am Ende garnix mit anfangen kann

    Auch von mir ein Willkommen in der Gegenwart. Gigabyte? Ne. Gerade EF Core ist SEHR schlank da nur noch das dabei ist was man schlussendlich benötigt, nicht wie bei EF 6. Stimmt schon, EF 6 war sehr groß, deshalb Arbeite ich auch nur noch mit EF Core.

    ErfinderDesRades schrieb:

    Das Prinzip "Dont repeat yourself" scheint ja inne Wpf-Datenbänkerei nicht mehr zu gelten.

    Was hat das mit EF zu tun. In EF wird mal gar nix wiederholt. Und teoretisch benötigt man auch die "Wrapper" nicht, es ist nur so das man in WPF sowieso mit ViewModels Arbeitet und sohin sowieso ViewModel Klassen macht.
    Egal ob man seine Daten jetzt durch EF bekommt, ne Testdatei, ne XML oder ähnliches einliest oder man mit DataSets arbeitet. Du bindest ja NIE direkt auf deine Daten sondern ladest diese in dein ViewModel oder? Also auf was genau willst du hinaus?

    ErfinderDesRades schrieb:

    Bei Codefirst - gibts da den von dir genannten Designer?

    Ja, auch für CodeFirst (sogar für das neu EF Core) gibt es die PowerTools welche dir jederzeit dein CodeFirst Model als Diagramm darstellen können.

    ErfinderDesRades schrieb:

    Und ich bezog mich auf NoFear, der sich von T4 recht unbegeistert zeigt.
    Und der T4-Kram - funktioniert das bei dir? Worauf habt ihr aufgebaut, und wie lange habt ihr gebraucht, es auf eure Bedürfnisse anzupassen?

    Ja, ich mag klicki-bunti Designer nicht. Und ich hasse es wenn mir Code generiert wird. Aber ich habe mich auch damit bereits öfters auseinandergesetzt und weis damit von was ich spreche.
    T4 funzt - definitiv, allerdings und das ist mal ganz wichtig - auch wenn es viele machen - man passt die Templates nicht an. Wozu auch. Was will ich dort implementieren??
    Ein Model bleibt ein Model. Fertig. Da muss ich weder Logik nocht sonst irgendeinen Kram reinbringen. Nur so bleibt ein Projekt sauber. Ich habe meine Layer. Jeder Layer hat eine andere Aufgabe. Macht ein Layer mal eine Aufagabe welche eigendlich einem anderen gehört ist das Chaos vorprogrammiert.


    ErfinderDesRades schrieb:

    und die Change-Trackerei fällt auch dem Feature-Cutting zum Opfer

    Wirklich? Ich denke du verwechselst das nun mit LazyLoading im EF Core. Ja, dieses ist bis jetzt entfallen und wird mit der 2.1 vermutlich wieder kommen. Leider
    Was ich schade finde. Ich fand es gut das man Entitäten explizit nachladen musste, so fing man sich keine Performanceprobleme ein. Der ChangeTracke ist immer und wird immer im EF an Board sein, sonst benötigt man ja keinen O/R Mapper oder?
    Oder meinst du das man kein ChangeTracking mehr hat wenn man mit einem ViewModel Arbeitet? Doch, hat man. Wenn man es richtig macht muss man sich um nichts kümmern.
    Es können 20 Layer mit 30 Wrapperklassen draumrum sein und man kann trotzdem den ChangeTracker vewrwenden wenn man es richtig macht.

    So, BackToTopic
    @Jeiss ich schau mir das Projekt gerne mal an und versuche es verständlich umzuändern.

    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. ##

    zum Projekt: Jo - alles gut, nur Ladefehler:
    "An attempt to attach an auto-named database for file C:\XXX\XXX\UrgentOrdersModelFirst.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."

    Tatsache ist, die mdf ist nicht da, wo sie wohl sein sollte. Meine VS-Installation hat beim SqlServer gefailt.

    Immerhin gibts das generierte Model, da binnich noch interessiert zu sehen, wie mans richtig macht, dass man zu einem brauchbaren Viewmodel kommt - ohne das generierte zumindest noch ein zweites mal programmieren zu müssen.

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

    Ja, er hat in der app.config einen festen Pfad zu seinem Benutzerprofil angegeben!!
    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,

    Nofear23m schrieb:

    ich schau mir das Projekt gerne mal an und versuche es verständlich umzuändern.


    Bin sehr froh dass ihr mir alle helfen wollt, weiss nämlich nicht mehr weiter!

    Es ist jetzt nicht mehr wichtig, die Struktur/den Aufbau des Projekts zu respektieren. Da ja eh nix geht!
    Also wenn es für euch einfacher ist, auf ein Projekt mit MVVM Struktur umzusteigen, dann nur los!
    Ich bin kein Ass was MVVM angeht, ist aber immer noch einfacher als das aktuelle Chaos.
    Macht es nur so kompliziert wie nötig, aber so einfach wie nur möglich um es euch selber zu erlauben mir bei späteren Problemchen weiter zu helfen..

    Denn auf so viele unerwartete Schwierigkeiten wie ich bis jetzt bei meinem "UrgentOrders"-Porjekt gestossen bin, kann ich fast nicht mehr glauben, dass es bald besser gehen wird...

    Update, 18:41.
    ​Hab mal kurz die mdf Datei hochgeladen. Falls ihr die gebrauchen könnt.

    Danke,
    Jeiss
    Dateien
    • Zipped DB.zip

      (378,77 kB, 162 mal heruntergeladen, zuletzt: )
    jo, die config hatte ich schon angepasst. Und nun hab ich die Datei auch hingelegt, aber ändert nix am Fehler

    An attempt to attach an auto-named database for file C:\[...]\UrgentOrdersModelFirst.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
    Wie gesagt: Wohl die Installation versaut.