Gruppieren nach mehreren Spalten in LINQ-Abfragen mit C#

Muhammad Husnain 12 Oktober 2023
  1. Einführung in LINQ
  2. Gruppieren nach mehreren Spalten in LINQ-Abfragen mit C#
Gruppieren nach mehreren Spalten in LINQ-Abfragen mit C#

Dieser Artikel bietet eine kurze Einführung in LINQ-Abfragen mit C#. Außerdem wird erläutert, wie Ergebnisse mithilfe von LINQ-Abfragen nach mehreren Spalten gruppiert werden.

Wenn Sie bereits mit LINQ vertraut sind, können Sie den Einführungsabschnitt getrost überspringen.

Einführung in LINQ

LINQ, was für Language Integrated Query steht, ist eine Methode, die uns eine einheitliche Methode für den Zugriff auf Daten aus verschiedenen Datenquellen wie Datenbanken, Arrays, XML und vielem mehr zur Verfügung stellt. Es kann alle Abfragen in sich integrieren.

Wenn Entwickler eine Anwendung entwickeln, benötigen sie neben einer Programmiersprache einige zusätzliche Kenntnisse, um Daten aus Datenquellen zu erfassen. Wenn Ihre Datenquelle beispielsweise eine Datenbank ist, benötigt ein Programmierer SQL-Kenntnisse.

Ebenso sollte der Programmierer wissen, wie man XML analysiert, wenn die Datenquelle ein XML-Dokument ist. Während Sie bei LINQ nur das Wissen über LINQ benötigen, um Daten aus all diesen Datenquellen zu erfassen.

LINQ-Architektur

LINQ zu Objekten

LINQ to Objects bedeutet, dass Sie LINQ-Abfragen verwenden können, um die Daten aus einer In-Memory-Datenstruktur abzurufen. Diese Datenstruktur kann benutzerdefiniert sein sowie einige DotNet-definierte APIs.

Die einzige Anforderung an die Datenstruktur ist, dass sie die Collection im Typ IEnummerable<T> zurückliefert.

Betrachten wir ein Beispiel für LINQ to Objects:

using System;
using System.Linq;

class MyProgram {
  static void Main() {
    string[] list = { "apple", "ball", "aeroplane", "beautiful", "ancient" };

    var starts = from w in list
                 where w.StartsWith("a") select w;
    // Print words
    foreach (var word in starts) {
      Console.WriteLine(word);
    }
  }
}

Ausgabe:

apple
aeroplane
ancient

Im obigen Codeausschnitt haben wir eine LINQ-Abfrage durchgeführt, um auf die Daten aus einem Zeichenfolgenarray zuzugreifen. Auf diese Weise kann dieses Array durch eine beliebige Datenstruktur ersetzt werden.

Der Vorteil der LINQ-Abfrage besteht darin, dass ihre Syntax gleich bleibt, unabhängig davon, ob Sie die Datenstruktur im Hintergrund ändern. Die Abfrage bleibt gleich; dies ist die von LINQ bereitgestellte Einheitlichkeit.

LINQ-zu-SQL

Für LINQ to ADO.Net gibt es 3 Unterkomponenten. Aber wir werden uns hauptsächlich auf LINQ to SQL konzentrieren.

LINQ to SQL ermöglicht es uns, die relationale Datenbank in Objekte umzuwandeln. Es macht Datenoperationen viel einfacher und schneller.

Der folgende Prozess besteht darin, dass zuerst eine Verbindung mit der Datenbank hergestellt wird, LINQ-Abfragen in SQL-Abfragen konvertiert werden und dann diese SQL-Abfragen ausgeführt werden. Das von SQL zurückgegebene Ergebnis wird zurück in von LINQ erstellte Objekte konvertiert und dann an den Benutzer zurückgegeben.

LINQ to SQL-Prozess

LINQ verfolgt auch die Änderungen in den Daten der Objekte und synchronisiert diese Änderungen automatisch in der Datenbank.

Wenn Sie in Ihrem Projekt eine LINQ to SQL-Komponente erstellen, werden automatisch die Klassen für alle Datenbanktabellen erstellt. Danach müssen Sie für die Verbindungs- und Datenbankoperationen codieren.

Angenommen, wir haben eine Tabelle zum Speichern der Daten von Mitarbeitern eines Unternehmens. Der Tabellenname ist Emp und enthält die Felder: Id, Name und Email.

Um es als LINQ-Abfragen zu verwenden, betrachten Sie das folgende Code-Snippet:

using System;
using System.Linq;

namespace MyLINQExample {
   class LINQExample {
      static void Main(string[] args) {

         string connectString = System.Configuration.ConfigurationManager.            ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
         LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
         Emp newEmp = new Emp();
         newEmp.name = "John";
         newEmp.email = "john@abccompany.com";
         newEmp.id = 3;
         //Add this new employee to the database
         db.Emps.InsertOnSubmit(newEmp);

         //To save changes in the database
         db.SubmitChanges();

         //Get the data of inserted employee
         Emp e = db.Emps.FirstOrDefault(e e.name.Equals("John"));

         Console.WriteLine("Emp Id = {0} , Name = {1}, Email = {2}",
                          e.id, e.name, e.email);

         Console.WriteLine("\nPress any key to continue.");
         Console.ReadKey();
      }
   }
}

Im obigen Code haben wir eine Verbindung zur Datenbank hergestellt, ein Datenkontextobjekt erstellt und dann unsere Abfrage auf der Datenbank ausgeführt.

Ausgabe:

Emp Id = 3, Name = John, Email = john@abccompany.com

Verknüpfungen in LINQ

Wie einfache SQL-Abfragen können Sie auch Spalten mit LINQ-Abfragen verbinden. Der Join-Vorgang wird ausgeführt, wenn Sie die Daten aus verschiedenen Tabellen basierend auf einer bestimmten Bedingung benötigen.

LINQ stellt den Operator join bereit, der einzelne oder mehrere Spalten einfach verbinden kann. Stellen Sie sich vor, wir haben die folgenden zwei Klassen:

public class Student {
  public int Stu_ID { get; set; }
  public string Stu_Name { get; set; }
  public int Class_ID { get; set; }
}

public class Grade {
  public int Grade_ID { get; set; }
  public string Grade_Name { get; set; }
}

Lassen Sie uns in der Treiberfunktion zwei Listen für jede Klasse wie folgt erstellen:

IList<Student> students_list = new List<Student>() {
  new Student() { Stu_ID = 11, Stu_Name = "ABC", Class_ID = 1 },
  new Student() { Stu_ID = 12, Stu_Name = "DEF", Class_ID = 1 },
  new Student() { Stu_ID = 13, Stu_Name = "GHI", Class_ID = 2 },
  new Student() { Stu_ID = 14, Stu_Name = "JKL", Class_ID = 2 },
};

IList<Grade> gradeList = new List<Grade>() { new Grade() { Grade_ID = 1, Grade_Name = "Grade 1" },
                                             new Grade() { Grade_ID = 2, Grade_Name = "Grade 2" },
                                             new Grade() { Grade_ID = 3, Grade_Name = "Grade 3" } };

Wenn wir nun die Namen der Schüler und ihrer Klassen erhalten möchten, müssen wir diese beiden Tabellen verbinden. Diese Tabellen werden basierend auf Class_ID bzw. Grade_ID verknüpft.

Die Join-Abfrage sieht folgendermaßen aus:

var joinResult =
    from s in student_list join g in gradeList on s.Class_ID equals g.Grade_ID select new {
      StuName = s.Stu_Name, GradeName = g.Grade_Name
    };

Dies ergibt die folgende Ausgabe:

ABC Grade 1
DEF Grade 1
GHI Grade 2
JKL Grade 2

Gruppieren nach mehreren Spalten in LINQ-Abfragen mit C#

Auf die gleiche Weise können wir die Daten auch basierend auf einem Attribut gruppieren. Dies geschieht über die Klausel GroupBy in der LINQ-Abfrage.

Der Operator GroupBy gibt basierend auf einem Schlüsselwert eine Teilmenge der Elemente in einer bereitgestellten Sammlung zurück. IGrouping<TKey, TElement>-Objekte repräsentieren jede Gruppe.

Darüber hinaus unterstützt die Methode GroupBy verschiedene Überladungsmethoden, sodass Sie je nach Bedarf die passende Erweiterungsmethode in der Methodensyntax verwenden können.

Betrachten Sie den folgenden Code:

List<Student> student_List = new List<Student>() {
  new Student() { Stu_ID = 11, Stu_Name = "ABC", Age = 18, Subject = "Arts" },
  new Student() { Stu_ID = 12, Stu_Name = "DEF", Age = 19, Subject = "Science" },
  new Student() { Stu_ID = 13, Stu_Name = "GHI", Age = 18, Subject = "Arts" },
  new Student() { Stu_ID = 14, Stu_Name = "JKL", Age = 19, Subject = "Science" },
};

Angenommen, wir möchten die Schülerliste nach Alter gruppiert erhalten. Die folgende Abfrage erledigt das für uns:

var result = from s in student_List group s by s.Age;

foreach (var ageGroups in result) {
  Console.WriteLine("Age Group: {0}", ageGroups.Key);
  foreach (Student s in ageGroups)  // Each group has inner collection
    Console.WriteLine("Student Name: {0}", s.Stu_Name);
}

Ausgabe:

Age Group: 18
Student Name: ABC
Student Name: GHI
Age Group: 19
Student Name: DEF
Student Name: JKL

Ebenso können wir auch nach mehreren Spalten gruppieren. Dies geschieht auf folgende Weise:

var result = from s in student_List group s by new { s.Age, s.Subject };
foreach (var ageGroups in groupedResult) {
  Console.WriteLine("Group: {0}", ageGroups.Key);

  foreach (Student s in ageGroups)  // Each group has inner collection
    Console.WriteLine("Student Name: {0}", s.Stu_Name);
}

Diese Abfrage ergibt die folgende Ausgabe:

Group: {Age= 18, Subject="Arts"}
Student Name: ABC
Student Name: GHI
Group: {Age= 19, Subject="Science"}
Student Name: DEF
Student Name: JKL
Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn

Verwandter Artikel - Csharp LINQ