Laden...

EF Core 7 / LINQ Abfrage mit Joins / Darstellung in DataGridView / automatische Aktualisierung

Letzter Beitrag vor einem Jahr 6 Posts 664 Views
EF Core 7 / LINQ Abfrage mit Joins / Darstellung in DataGridView / automatische Aktualisierung

Hallo!

Ich bin mit dem Entity Framework Core 7 relativ neu unterwegs und komme an dieser Stelle nicht weiter:

Ich habe eine LINQ-Abfrage mit Joins über mehrere Tabellen aus meinem DbContext und projiziere das Ergebnis mit "select new xyz()" und ToList() über einen BindingSource in die DataSource eines DataGridView's. Wenn nun in der zugrundliegenden Haupttabelle ein Datensatz hinzugefügt wird, wird das DataGridView nicht aktualisiert.

            var query = from az in Context.ArbZeiten
                       where az.MitarbId == MitarbeiterId
                       join kat in Context.Kategorie on az.KatId equals kat.Id
                       join ort in Context.Orte on az.OrtId equals ort.Id
                       join prj in Context.vAuftraege on az.AuftragId equals prj.BELEG_ID
                       orderby az.Id
                       select new ArbZeitenSicht()
                       {
                           Bearbeitet = az.Bearbeitet,
                           Projekt = prj.Projekt,
                           Bezeichnung = prj.Bezeichnung,
                           Auftrag = az.Auftrag,
                           Kategorie = kat.Kategorie1,
                           Datum = az.Datum,
                           Beginn = az.Beginn,
                           Ende = az.Ende,
                           Pause = az.Pause,
                           Ort = ort.Ort,
                           Reise = az.Reise,
                           Km = az.Km,
                           Beschreibung = az.Beschreibung
                       };
               BindingSource bs = new BindingSource();
               bs.DataSource = query.ToList();
               DgvArbZeiten.DataSource = bs;

Im DbContext:

  public virtual DbSet<ArbZeitenSicht> ArbZeitenSicht { get; set; }
  
  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
          modelBuilder.Entity<ArbZeitenSicht>(entity => 
        {
            entity
                .HasNoKey();
        });
       OnModelCreatingPartial(modelBuilder);

  }

Ist das überhaupt der richtige Weg? Welches ist der beste Weg, um einen solchen Fall mit dem EF zu lösen? Ich stehe da im Moment etwas auf dem Schlauch....

Vielen Dank für Eure Tipps und Hinweise!

Hier hast du gleich mehrere Probleme.
Zum einen arbeitet man in der UI nicht mit dem DbContext bzw. vermischt man nicht die Datenhaltung mit der UI.

Ebenfalls machst du auch ein ToList, was die Daten aus der DB einlädt und materialisiert.
Dadurch ist die Liste und die Objekte darin eigenständige Objekte.
Bei Änderungen an deinem Datenstand wird sich das Grid nicht selbst updaten.
Dies müsstest du in deinem Programm selbst lösen.
Wenn z.B. über das Grid Einträge angelegt werden, musst du diese auch der DataSource hinzufügen und in der DB anlegen.
Ansonsten ist dein aktuelle Vorgehen unbekannt bzw. nicht beschrieben.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Danke für die schnelle Antwort!

Im echten Programmcode ist das schon getrennt, ich habe es hier der Übersicht halber zusammen dargestellt. Ich habe noch eine weitere Möglichkeit gefunden, die dokumentiert wird und zwar mit der Erweiterungsmethode ToBindingList(). Damit funktioniert es mit einer "normalen" Tabelle, die DataGridView wird automatisch aktualisiert:

                Context.ArbZeiten.Load();
                BindingSource bs = new BindingSource();
                bs.DataSource = Context.ArbZeiten.Local.ToBindingList();
                DgvArbZeiten.DataSource = bs;

Mein Problem ist, wie kriege ich genau das mit einer Liste hin, die so wie unten gezeigt durch eine LINQ-Abfrage erzeugt wird?

Danke!

In der Form gar nicht, weil Du mit Projektionen arbeitest. Deine Modelle sind Ausschnitte aus verschiedenen Tabellen. 
Das kann und wird nicht in die andere Seite aufgelöst; keine Software kann hellsehen.

Du musst hier den neuen Eintrag manuell erkennen und einen eigenen Sql-Befehl absetzen, das die Entitäten in die DB schreibt.
Der Weg ist aber der richtige: so lädt man effizient Daten. Aber geschenkt bekommt man hier leider nix*

*man kann sich die Projektionen durch LinqKit Profiles schenken lassen; aber das ist nur in Hilsmittel fürs Lesen.

Danke für die Hinweise!

Schade, ich hoffte es gäbe da eine Möglichkeit. Denn es sind ja alle Tabellen und Relationen aus der DB im EF abgebildet. Und beim Materialisieren der LINQ-Abfrage werden ja auch alle Daten entsprechend der Relationen aus der DB geladen.

Nein, nicht möglich. Dazu bräuchte es schwarze Magie.

Projektionen sind immer und überall (nicht nur .NET, nicht nur EF, nicht nur SQL) ein One-Way-Mechanismus.