WPF EF Code-First Datenbanksample

    • XAML: WPF
    • .NET (FX) 4.5–4.8

    Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Rinecamo.

      WPF EF Code-First Datenbanksample

      Ich habe mir anlässlich dieses Threads ein Sample aus einer mir bereits bekannten Anwendung gemacht.
      Hierbei gibt es zwei Dinge: Ein Container, der unterschiedliche Dinge beinhaltet Container und ein ContainerItem, was nichts anderes als einen Text und eine Beschreibung beinhaltet.
      Das gesamte Projekte wurde mit Visual Studio 2015 RC sowie den C# 5 Sprachfeatures ersetellt. Gezielt wird auf .NET 4.5. Alle verwendeten Bibliotheken sind über NuGet erreichbar.
      Auf der linken Seite werden alle Container aufgelistet und auf der rechten Seite einige Informationen und die zugeordneten Items.
      Das gesamte Sample ist so minimal gehalten wie nur irgendmöglich, weswegen folgende Features nicht vorhanden sind: Entfernen von Items, Entfernen von Containern, Validierung. Sofern Bedarf besteht, kann ich dieses Beispiel gerne erweitern.
      Die Anwendung selbst ist einige KB groß, die Abhängigkeiten nehmen daneben noch rund 20 MB ein (kann durch entfernen der .xml-Dateien halbiert werden).

      Hier nun der Code dazu: EFBindingSample-Source.zip
      Ich biete keinen Support bei Versuch die Solution in VS < 2015 zu öffnen. Es ist möglich, ihr müsst nur alle nameof() durch literale ersetzen und die Auto-Property-Initialisierer durch eigene Konstrukte ersetzen.
      Die ausführbaren Dateien sind ebenfalls angehängt. Sollte überall laufen, wo WPF und .NET 4.5 vorhanden sind. EFBindingSample-Bin.zip

      Nach Wunsch des @ErfinderDesRades habe ich den Code auf C# 5-Niveau gebracht. Damit sollte er in allen IDEs ab 2012 laufen.

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

      Hmm - ich finde darin diese Zeile (Container.cs):

      C#-Quellcode

      1. public virtual IReactiveList<ContainerItem> Items { get; } = new ReactiveList<ContainerItem>() { ChangeTrackingEnabled = true };
      Ich vermute ein c#6 - Feature.
      Wär's dir möglich, die Geschichte zu downgraden, dasses auch für 2013-VisualStudios nutzbar ist?

      achnee - haste ja schon verneint, schade :(

      Edit-Edit-Edit: Jo, jetzt gehts! :thumbsup:
      Musste noch alle möglichen Verweise neu setzen, aber das ist ja leistbar dank der Bin.zip. :)

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

      Ich habe eingesehen, dass es eventuell etwas voreilig ist, bei einem RC schon direkt davon auszugehen, dass jeder sich mit den Sprachfeatures auseinandersetzt. Deswegen habe ich den Code doch noch auf C# 5 angepasst.
      Damit sollte er aber jetzt tatsächlich bei dir laufen.
      Hi!
      Mir ist noch was verdächtiges aufgefallen, nämlich dass dein ContainerContext mehrfach instanziert wird. Ich habe auch eine Zeitmessung angestellt, die die Zeitpunkte festhält, wann der Konstruktor betreten und wieder verlassen wird - es sieht aus, als ob zunächstmal generell, und dann pro .LoadAsync() einmal.
      Das hängt mit den Rx-Listen zusammen, denn ohne die kann man einen richtigen Singleton davon machen - also den Constructor private setzen.
      Die Mehrfach-Instanzierung hat aber keine erkennbare Schadens-Wirkung, scheint allerdings nochmal eine zusätzliche Sekunde Lade-Zeit in Anspruch zu nehmen.

      Hier der ContainerContext mit "Mess-Anlage":

      C#-Quellcode

      1. using System;
      2. using System.Data.Entity;
      3. using System.Linq;
      4. using System.Diagnostics;
      5. namespace EFBindingSample.Data {
      6. public class ContainerContext : DbContext {
      7. private static Lazy<ContainerContext> context = new Lazy<ContainerContext>(() => new ContainerContext());
      8. public static ContainerContext Instance { get { return context.Value; } }
      9. public DbSet<Container> Container { get; set; }
      10. public DbSet<ContainerItem> Items { get; set; }
      11. private static Stopwatch _SW;
      12. private static string LogPassThrough(string retVal = null) {
      13. if (retVal != null) {
      14. Debug.Print("Enter");
      15. if (_SW !=null) return retVal;
      16. _SW = Stopwatch.StartNew();
      17. }
      18. else Debug.Print("Exit {0} ms", _SW.ElapsedMilliseconds);
      19. return retVal;
      20. }
      21. public ContainerContext()
      22. : base(LogPassThrough("ContainerContext")) {
      23. Configuration.LazyLoadingEnabled = false;
      24. foreach (var dbs in new IQueryable[] { Container, Items }) dbs.LoadAsync();
      25. LogPassThrough();
      26. }
      27. /* Original-Code:
      28. public ContainerContext()
      29. : base("ContainerContext2") {
      30. Configuration.LazyLoadingEnabled = false;
      31. foreach (var dbs in new IQueryable[] { Container, Items }) dbs.LoadAsync();
      32. }
      33. */
      34. }
      35. }
      Ausgabe:

      Quellcode

      1. Enter
      2. Enter
      3. Exit 3603 ms
      4. Enter
      5. Exit 3632 ms
      6. Enter
      7. Exit 4886 ms
      8. Exit 4938 ms

      Hallo,

      leider erhalte ich beim Erstellen dieses Projektes eine Fehlermeldung, bezogen auf die Zeile:

      C#-Quellcode

      1. public IReactiveDerivedList<ContainerItemViewModel> Items { get; }


      Fehler 1 'EFBindingSample.ViewModel.ContainerViewModel.Items.get' ist nicht als abstrakt oder extern gekennzeichnet und muss daher einen Text deklarieren. Automatisch implementierte Eigenschaften müssen get- und set-Accessoren definieren.
      ...\Visual Studio 2013\Projects\Tools\EFBindingSample-Source\EFBindingSample\ViewModel\ContainerViewModel.cs 28 63 EFBindingSample

      Leider sagt mir dies rein gar nichts - kann da evtl. bitte jemand helfen?

      Meine IDE: VS 2013