Bagikan melalui


Gambaran Umum Operator Kueri Standar

Operator kueri standar adalah kata kunci dan metode yang membentuk pola LINQ. Bahasa C# menentukan kata kunci kueri LINQ yang Anda gunakan untuk ekspresi kueri yang paling umum. Pengkompilasi menerjemahkan ekspresi menggunakan kata kunci ini ke panggilan metode yang setara. Dua bentuk tersebut identik. Metode lain yang merupakan bagian System.Linq dari namespace tidak memiliki kata kunci kueri yang setara. Dalam kasus tersebut, Anda harus menggunakan sintaksis metode. Bagian ini mencakup semua kata kunci operator kueri. Runtime dan paket NuGet lainnya menambahkan lebih banyak metode yang dirancang untuk bekerja dengan kueri LINQ pada setiap rilis. Metode yang paling umum, termasuk yang memiliki kata kunci kueri yang setara dibahas di bagian ini. Untuk daftar lengkap metode kueri yang didukung oleh .NET Runtime, lihat System.Linq.Enumerable dokumentasi API. Selain metode yang dibahas di sini, kelas ini berisi metode untuk menggabungkan sumber data, menghitung satu nilai dari sumber data, seperti jumlah, rata-rata, atau nilai lainnya.

Penting

Sampel ini menggunakan System.Collections.Generic.IEnumerable<T> sumber data. Sumber data berdasarkan System.Linq.IQueryProvider penggunaan System.Linq.IQueryable<T> sumber data dan pohon ekspresi. Pohon ekspresi memiliki batasan pada sintaks C# yang diizinkan. Selain itu, setiap IQueryProvider sumber data, seperti EF Core dapat memberlakukan lebih banyak batasan. Periksa dokumentasi untuk sumber data Anda.

Sebagian besar metode ini beroperasi pada urutan, di mana urutannya adalah objek yang jenisnya mengimplementasikan IEnumerable<T> antarmuka atau IQueryable<T> antarmuka. Operator kueri standar menyediakan kemampuan kueri termasuk pemfilteran, proyeksi, agregasi, pengurutan, dan lainnya. Metode yang membentuk setiap set adalah anggota statis dari kelas Enumerable dan Queryable masing-masing. Mereka didefinisikan sebagai metode ekstensi dari jenis yang mereka operasikan.

Perbedaan antara IEnumerable<T> dan IQueryable<T> urutan menentukan bagaimana kueri dijalankan pada runtime.

Untuk IEnumerable<T>, objek enumerabel yang dikembalikan menangkap argumen yang diteruskan ke metode . Ketika objek tersebut dijumlahkan, logika operator kueri digunakan dan hasil kueri dikembalikan.

Untuk IQueryable<T>, kueri diterjemahkan ke dalam pohon ekspresi. Pohon ekspresi dapat diterjemahkan ke kueri asli saat sumber data dapat mengoptimalkan kueri. Pustaka seperti Entity Framework menerjemahkan kueri LINQ ke dalam kueri SQL asli yang dijalankan di database.

Contoh kode berikut menunjukkan bagaimana operator kueri standar dapat digunakan untuk mendapatkan informasi tentang urutan.

string sentence = "the quick brown fox jumps over the lazy dog";
// Split the string into individual words to create a collection.
string[] words = sentence.Split(' ');

// Using query expression syntax.
var query = from word in words
            group word.ToUpper() by word.Length into gr
            orderby gr.Key
            select new { Length = gr.Key, Words = gr };

// Using method-based query syntax.
var query2 = words.
    GroupBy(w => w.Length, w => w.ToUpper()).
    Select(g => new { Length = g.Key, Words = g }).
    OrderBy(o => o.Length);

foreach (var obj in query)
{
    Console.WriteLine($"Words of length {obj.Length}:");
    foreach (string word in obj.Words)
        Console.WriteLine(word);
}

// This code example produces the following output:
//
// Words of length 3:
// THE
// FOX
// THE
// DOG
// Words of length 4:
// OVER
// LAZY
// Words of length 5:
// QUICK
// BROWN
// JUMPS

Jika memungkinkan, kueri di bagian ini menggunakan urutan kata atau angka sebagai sumber input. Untuk kueri di mana hubungan yang lebih rumit antara objek digunakan, sumber berikut yang memodelkan sekolah digunakan:

public enum GradeLevel
{
    FirstYear = 1,
    SecondYear,
    ThirdYear,
    FourthYear
};

public class Student
{
    public required string FirstName { get; init; }
    public required string LastName { get; init; }
    public required int ID { get; init; }

    public required GradeLevel Year { get; init; }
    public required List<int> Scores { get; init; }

    public required int DepartmentID { get; init; }
}

public class Teacher
{
    public required string First { get; init; }
    public required string Last { get; init; }
    public required int ID { get; init; }
    public required string City { get; init; }
}

public class Department
{
    public required string Name { get; init; }
    public int ID { get; init; }

    public required int TeacherID { get; init; }
}

Masing-masing Student memiliki tingkat kelas, departemen utama, dan serangkaian skor. A Teacher juga memiliki City properti yang mengidentifikasi kampus tempat guru mengadakan kelas. A Department memiliki nama, dan referensi untuk siapa Teacher yang menjabat sebagai kepala departemen.

Anda dapat menemukan himpunan data di repositori sumber.

Jenis operator kueri

Operator kueri standar berbeda dalam waktu eksekusinya, tergantung pada apakah operator mengembalikan nilai singleton atau urutan nilai. Metode yang mengembalikan nilai singleton (seperti Average dan Sum) segera dijalankan. Metode yang mengembalikan urutan menunda eksekusi kueri dan mengembalikan objek yang dapat dijumlahkan. Anda bisa menggunakan urutan output dari satu kueri sebagai urutan input ke kueri lain. Panggilan ke metode kueri dapat digabungkan dalam satu kueri, yang memungkinkan kueri menjadi kompleks sesuai kebutuhan.

Operator kueri

Dalam kueri LINQ, langkah pertama adalah menentukan sumber data. Dalam kueri LINQ, from klausul menjadi yang pertama untuk memperkenalkan sumber data (students) dan variabel rentang (student).

//queryAllStudents is an IEnumerable<Student>
var queryAllStudents = from student in students
                        select student;

Variabel rentang seperti variabel iterasi dalam perulangan foreach kecuali bahwa tidak ada iterasi aktual yang terjadi dalam ekspresi kueri. Ketika kueri dijalankan, variabel rentang berfungsi sebagai referensi ke setiap elemen berturut-turut di students. Karena pengkompilasi dapat menyimpulkan jenis student, Anda tidak perlu menentukannya secara eksplisit. Anda dapat memperkenalkan lebih banyak variabel rentang dalam klausa let . Untuk informasi selengkapnya, lihat biarkan klausa.

Nota

Untuk sumber data non-generik seperti ArrayList, variabel rentang harus ditik secara eksplisit. Untuk informasi selengkapnya, lihat Cara mengkueri ArrayList dengan LINQ (C#) dan dari klausa.

Setelah mendapatkan sumber data, Anda dapat melakukan sejumlah operasi pada sumber data tersebut:

Tabel Sintaks Ekspresi Query

Tabel berikut mencantumkan operator kueri standar yang memiliki klausul ekspresi kueri yang setara.

Metode Sintaks kueri ekspresi C#
Cast Gunakan variabel rentang yang ditik secara eksplisit:

from int i in numbers

(Untuk informasi selengkapnya, lihat klausa FROM.)
GroupBy group … by

-atau-

group … by … into …

(Untuk informasi selengkapnya, lihat klausa grup.)
GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>, TResult>) join … in … on … equals … into …

(Untuk informasi selengkapnya, lihat klausa gabungan.)
Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>) join … in … on … equals …

(Untuk informasi selengkapnya, lihat klausa gabungan.)
OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>) orderby

(Untuk informasi selengkapnya, lihat klausa orderby.)
OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>) orderby … descending

(Untuk informasi selengkapnya, lihat klausa orderby.)
Select select

(Untuk informasi selengkapnya, lihat memilih klausa.)
SelectMany Beberapa from klausa.

(Untuk informasi selengkapnya, lihat klausa FROM.)
ThenBy<TSource,TKey>(IOrderedEnumerable<TSource>, Func<TSource,TKey>) orderby …, …

(Untuk informasi selengkapnya, lihat klausa orderby.)
ThenByDescending<TSource,TKey>(IOrderedEnumerable<TSource>, Func<TSource,TKey>) orderby …, … descending

(Untuk informasi selengkapnya, lihat klausa orderby.)
Where where

(Untuk informasi selengkapnya, lihat klausa di mana.)

Transformasi Data dengan LINQ

Language-Integrated Query (LINQ) tidak hanya tentang mengambil data. Ini juga merupakan alat yang ampuh untuk mengubah data. Dengan menggunakan kueri LINQ, Anda dapat menggunakan urutan sumber sebagai input dan memodifikasinya dalam banyak cara untuk membuat urutan output baru. Anda dapat memodifikasi urutan itu sendiri tanpa memodifikasi elemen itu sendiri dengan mengurutkan dan mengelompokkan. Tetapi mungkin fitur paling kuat dari kueri LINQ adalah kemampuan untuk membuat jenis baru. Klausa pilih membuat elemen output dari elemen input. Anda menggunakannya untuk mengubah elemen input menjadi elemen output:

  • Gabungkan beberapa urutan input ke dalam satu urutan output yang memiliki jenis baru.
  • Buat urutan output yang elemennya hanya terdiri dari satu atau beberapa properti dari setiap elemen dalam urutan sumber.
  • Buat urutan output yang elemennya terdiri dari hasil operasi yang dilakukan pada data sumber.
  • Buat urutan output dalam format yang berbeda. Misalnya, Anda dapat mengubah data dari baris SQL atau file teks menjadi XML.

Transformasi ini dapat digabungkan dengan berbagai cara dalam kueri yang sama. Selain itu, urutan output dari satu kueri dapat digunakan sebagai urutan input untuk kueri baru. Contoh berikut mengubah objek dalam struktur data dalam memori menjadi elemen XML.


// Create the query.
var studentsToXML = new XElement("Root",
    from student in students
    let scores = string.Join(",", student.Scores)
    select new XElement("student",
                new XElement("First", student.FirstName),
                new XElement("Last", student.LastName),
                new XElement("Scores", scores)
            ) // end "student"
        ); // end "Root"

// Execute the query.
Console.WriteLine(studentsToXML);

Kode menghasilkan output XML berikut:

<Root>
  <student>
    <First>Svetlana</First>
    <Last>Omelchenko</Last>
    <Scores>97,90,73,54</Scores>
  </student>
  <student>
    <First>Claire</First>
    <Last>O'Donnell</Last>
    <Scores>56,78,95,95</Scores>
  </student>
  ...
  <student>
    <First>Max</First>
    <Last>Lindgren</Last>
    <Scores>86,88,96,63</Scores>
  </student>
  <student>
    <First>Arina</First>
    <Last>Ivanova</Last>
    <Scores>93,63,70,80</Scores>
  </student>
</Root>

Untuk informasi selengkapnya, lihat Membuat Pohon XML di C# (LINQ ke XML).

Anda bisa menggunakan hasil satu kueri sebagai sumber data untuk kueri berikutnya. Contoh ini menunjukkan cara mengurutkan hasil operasi gabungan. Kueri ini membuat gabungan grup, lalu mengurutkan grup berdasarkan elemen kategori, yang masih dalam cakupan. Dalam penginisialisasi tipe anonim, subkueri mengurutkan semua elemen yang cocok dari urutan produk.

var orderedQuery = from department in departments
                   join student in students on department.ID equals student.DepartmentID into studentGroup
                   orderby department.Name
                   select new
                   {
                       DepartmentName = department.Name,
                       Students = from student in studentGroup
                                  orderby student.LastName
                                    select student
                   };

foreach (var departmentList in orderedQuery)
{
    Console.WriteLine(departmentList.DepartmentName);
    foreach (var student in departmentList.Students)
    {
        Console.WriteLine($"  {student.LastName,-10} {student.FirstName,-10}");
    }
}
/* Output:
Chemistry
  Balzan     Josephine
  Fakhouri   Fadi
  Popov      Innocenty
  Seleznyova Sofiya
  Vella      Carmen
Economics
  Adams      Terry
  Adaobi     Izuchukwu
  Berggren   Jeanette
  Garcia     Cesar
  Ifeoma     Nwanneka
  Jamuike    Ifeanacho
  Larsson    Naima
  Svensson   Noel
  Ugomma     Ifunanya
Engineering
  Axelsson   Erik
  Berg       Veronika
  Engström   Nancy
  Hicks      Cassie
  Keever     Bruce
  Micallef   Nicholas
  Mortensen  Sven
  Nilsson    Erna
  Tucker     Michael
  Yermolayeva Anna
English
  Andersson  Sarah
  Feng       Hanying
  Ivanova    Arina
  Jakobsson  Jesper
  Jensen     Christiane
  Johansson  Mark
  Kolpakova  Nadezhda
  Omelchenko Svetlana
  Urquhart   Donald
Mathematics
  Frost      Gaby
  Garcia     Hugo
  Hedlund    Anna
  Kovaleva   Katerina
  Lindgren   Max
  Maslova    Evgeniya
  Olsson     Ruth
  Sammut     Maria
  Sazonova   Anastasiya
Physics
  Åkesson    Sami
  Edwards    Amy E.
  Falzon     John
  Garcia     Debra
  Hansson    Sanna
  Mattsson   Martina
  Richardson Don
  Zabokritski Eugene
*/

Kueri yang setara menggunakan sintaks metode diperlihatkan dalam kode berikut:

var orderedQuery = departments
    .GroupJoin(students, department => department.ID, student => student.DepartmentID,
    (department, studentGroup) => new
    {
        DepartmentName = department.Name,
        Students = studentGroup.OrderBy(student => student.LastName)
    })
    .OrderBy(department => department.DepartmentName);


foreach (var departmentList in orderedQuery)
{
    Console.WriteLine(departmentList.DepartmentName);
    foreach (var student in departmentList.Students)
    {
        Console.WriteLine($"  {student.LastName,-10} {student.FirstName,-10}");
    }
}

Meskipun Anda dapat menggunakan klausul orderby dengan satu atau beberapa urutan sumber sebelum digabungkan, umumnya kami tidak merekomendasikannya. Beberapa penyedia LINQ mungkin tidak mempertahankan urutan tersebut setelah bergabung. Untuk informasi selengkapnya, lihat klausa gabungan .

Lihat juga