Nachhilfe Group By LINQ

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Nachhilfe Group By LINQ

    Hallo,

    die Group By Syntax war mir nie klar geworden, jetzt krieg da langsam mehr mit hin als ich verstehe.

    Anhand verschiedener Beispiele möchte ich meinen Kenntnisstand einmal durchgehen und dann entsprechende Fragen stellen

    VB.NET-Quellcode

    1. Dim q1 = From t In DS1.table
    2. Dim q2 = From t In DS1.table Group t By t.Key Into Group
    3. Dim q3 = From t In DS1.table Group t By t.Key Into g = Group
    4. Dim q4 = From t In DS1.table Group t By t.Key Into g = Group, Sum(t.Stueck)

    q1 gibt eine Sammlung an tableRows
    q2 und q3 geben eine Sammlung an anonymen Typen, deren Properties einmal der Key der Gruppe nach dem gruppiert werden soll und einmal eine Sammlung an tableRows sind,
    wobei die Sammlungs-Property bei q2 "Group" heißt und bei q3 "g". Ist dieses Into Group nur für diese Umbenennungsfunktionalität drin?
    bei q4 bekomme ich eine zusätzliche Property "Sum", genauso für weitere Aggregatsfunktionen.

    So habe ich Sum noch nie genutzt, normalerweise braucht man da einen Lambdaausdruck. Wenn ich im Studio die Funktion anschaue steht da Sum(selector as Func(... usw.
    Ist das die Definition eines Lambdaausdrucks?
    Warum funktioniert eine Spalte aus t hier als Argument? Das ist dann ja eigentlich ein Sum(x as Double) o.ä

    Achja und warum muss man explizit schreiben Group t By statt Group By?

    Viele Grüße

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

    Into gibt eine Aggregat-Funktion an.
    Eine Aggregat-Funktion ist eine, die aus einer Sammlung einen Einzelwert macht. Summe ist etwa eine Aggregat-Funktion.
    Sum() ist überladen. Man kann die Elemente der Sammlung direkt aufsummieren (wenn diese das unterstützen).
    Oder man kann etwas (zb ein Property, wie Stueck) von den Elementen auswählen, für die Summenbildung.
    Group By gruppiert also, und jede Gruppe wird aufsummiert

    Group() ist auch eine Aggregat-Funktion - die macht aber aus einer Sammlung nicht einen Einzelwert, sondern lässt die Gruppe wie sie ist.
    Group By gruppiert also, und jede Gruppe bleibt eine Sammlung.
    Du hattest vorher eine grosse Sammlung, nun hast du viele kleine Sammlungen, die Gruppen, und die Elemente innerhalb einer Gruppe weisen denselben GruppierSchlüssel auf.

    (ich weiss, das beantwortet nicht alle deine Fragen, aber ein paar vielleicht)
    Ah ok, das hat schonmal bisschen geholfen, sowas hatte ich noch nicht auf dem Schirm ich dachte "into group" ist Pflicht:

    VB.NET-Quellcode

    1. Dim q2 = From t In DS1.table Group t By t.Key Into Sum(t.Stueck)

    Das ist nun also die SQL-Like-Funktionalität.

    Eine solche Überladung habe ich bei Enumerable.Sum nicht, der will überall ein selector as Func() nur ist der Rückgabewerte decimal/double/etc
    Ist das vielleicht eine Überschreibung?
    jo, das ist halt die dolle Linq-Schreibweise, die so schön aussieht wie Sql.
    In Wahrheit sinds auch nix weiter als Extension-Methods, die da bemüht werden:

    VB.NET-Quellcode

    1. Dim q2 = From t In DS1.table Group t By t.Key Into Sum(t.Stueck)
    2. Dim q3 = DS1.table.GroupBy(Function(t) t.Key).Sum((Function(t)t.Stueck)
    (kann sein ist falsch, ich kann ja dein DS1 nicht testen)
    Also entweder es gibt eine Entsprechung oder es gibt sie nicht. Wird bei der Extension schreibweise auch q3 verzögert ausgewertet?
    Ich finde durch die andere Schreibweise lässt sich diese Eigenart sehr gut merken. Gewohntermaßen werden Extensions ja hintereinander abgearbeitet als wären es separate Zeilen. In query-Schreibweise wirkt es wie ein Satz der nur als Ganzes funktioniert.
    Zu jeder in Linq formulierten Query lässt sich Extension-Entsprechung formulieren.
    Wie gesagt: Linq-Ausdrücke sind nur eine andere Schreibweise der Extension-Formulierung.
    Oft gehts auch andersrum, dass man Linq-Extension-Queries auch in Linq-Syntax schreiben kann. Aber niccht immer - Linq-Syntax kann nur einen Ausschnitt dessen, was die Extension-Schreibweise kann.
    Wenn man eine Query formuliert, dann wird diese ja erst ausgeführt, wenn man ein Ergebnis abruft. Z.B.:

    VB.NET-Quellcode

    1. Dim q = From t in DS1.dt1 Where t.x = 1
    2. Dim Erg = q.Count 'Query läuft erst hier

    Ist das bei der Extension Schreibweise auch so?

    VB.NET-Quellcode

    1. Dim q = DS1.dt1.Where(Function(t) t.x = 1)
    2. Dim Erg = q.Count


    Anders gefragt sind das wirklich nur unterschiedliche Schreibweisen oder vielleicht unterschiedliche Mechanismen?
    Weil wenn die eine Richtung nicht immer klappt dann scheint es da ja doch irgendwie mehr zu geben als nur die Syntax

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

    AFAIK sind IEnumerables immer lazy evaluation-Geschichten. Erst, wenn die einzelnen Items abgefragt werden oder Lists oder Arrays, also andere Objekte, aus den IEnumerables gemacht werden, wird die Anfrage ausgeführt. Vorher sind es nur - ich sach mal - Abfragevorbereitungen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    nein, IEnumerables sind nicht immer lazyLoading. Es ist halt ein Interface, und kann lazyloadend implementiert sein, mussabernich. List(Of T) ist auch IEnumerable.
    Eiglich weissich nur von Linq.Select(), dasses lazyLoading ist.
    Dann ist IQueryable glaub meist lazy, und LinqToSql, also so EF-Dinge, die im Hintergrund in eine DB greifen.