Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam tutorial ini, Anda membuat sumber data dan menulis beberapa kueri LINQ. Anda dapat bereksperimen dengan ekspresi kueri dan melihat perbedaan dalam hasilnya. Panduan ini menunjukkan fitur bahasa C# yang digunakan untuk menulis ekspresi kueri LINQ. Anda dapat mengikuti dan membangun aplikasi dan bereksperimen dengan kueri sendiri. Artikel ini mengasumsikan Anda telah menginstal .NET SDK terbaru. Jika tidak, buka halaman .NET Downloads dan instal versi terbaru di komputer Anda.
Pertama, buat aplikasi. Dari konsol, ketik perintah berikut:
dotnet new console -o WalkthroughWritingLinqQueries
Atau, jika Anda lebih suka Visual Studio, buat aplikasi konsol baru bernama WalkthroughWritingLinqQueries.
Membuat sumber data dalam memori
Langkah pertama adalah membuat sumber data untuk kueri Anda. Sumber data untuk kueri adalah daftar sederhana rekaman Student
. Setiap catatan Student
memiliki nama depan, nama belakang, dan array bilangan bulat yang mewakili skor ujian mereka di kelas. Tambahkan file baru bernama students.cs, dan salin kode berikut ke dalam file tersebut:
namespace WalkthroughWritingLinqQueries;
public record Student(string First, string Last, int ID, int[] Scores);
Perhatikan karakteristik berikut:
- Catatan
Student
terdiri dari properti yang diimplementasikan secara otomatis. - Setiap siswa dalam daftar diinisialisasi dengan konstruktor utama.
- Deretan nilai untuk setiap siswa diinisialisasi dengan menggunakan konstruktor utama.
Selanjutnya, buat urutan rekaman Student
yang berfungsi sebagai sumber kueri ini. Buka Program.cs, dan hapus kode boilerplate berikut:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Ganti dengan kode berikut yang membuat sebuah urutan rekaman Student
:
using WalkthroughWritingLinqQueries;
// Create a data source by using a collection initializer.
IEnumerable<Student> students =
[
new Student(First: "Svetlana", Last: "Omelchenko", ID: 111, Scores: [97, 92, 81, 60]),
new Student(First: "Claire", Last: "O'Donnell", ID: 112, Scores: [75, 84, 91, 39]),
new Student(First: "Sven", Last: "Mortensen", ID: 113, Scores: [88, 94, 65, 91]),
new Student(First: "Cesar", Last: "Garcia", ID: 114, Scores: [97, 89, 85, 82]),
new Student(First: "Debra", Last: "Garcia", ID: 115, Scores: [35, 72, 91, 70]),
new Student(First: "Fadi", Last: "Fakhouri", ID: 116, Scores: [99, 86, 90, 94]),
new Student(First: "Hanying", Last: "Feng", ID: 117, Scores: [93, 92, 80, 87]),
new Student(First: "Hugo", Last: "Garcia", ID: 118, Scores: [92, 90, 83, 78]),
new Student("Lance", "Tucker", 119, [68, 79, 88, 92]),
new Student("Terry", "Adams", 120, [99, 82, 81, 79]),
new Student("Eugene", "Zabokritski", 121, [96, 85, 91, 60]),
new Student("Michael", "Tucker", 122, [94, 92, 91, 91])
];
- Urutan siswa diinisialisasi dengan ekspresi koleksi.
- Jenis catatan
Student
memuat daftar statis semua siswa. - Beberapa panggilan konstruktor menggunakan argumen bernama untuk mengklarifikasi argumen mana yang cocok dengan parameter konstruktor mana.
Cobalah menambahkan beberapa siswa lagi dengan skor tes yang berbeda ke daftar siswa untuk lebih terbiasa dengan kode sejauh ini.
Membuat kueri
Selanjutnya, Anda membuat kueri pertama Anda. Kueri Anda, saat Anda menjalankannya, menghasilkan daftar semua siswa yang skornya pada tes pertama lebih besar dari 90. Karena seluruh objek Student
dipilih, tipe kueri IEnumerable<Student>
. Meskipun kode juga dapat menggunakan pengetikan implisit dengan menggunakan kata kunci var, pengetikan eksplisit digunakan untuk menggambarkan hasil dengan jelas. (Untuk informasi selengkapnya tentang var
, lihat Variabel Lokal yang Di ketik secara Implisit.) Tambahkan kode berikut ke Program.cs, setelah kode yang membuat urutan siswa:
// Create the query.
// The first line could also be written as "var studentQuery ="
IEnumerable<Student> studentQuery =
from student in students
where student.Scores[0] > 90
select student;
Variabel rentang kueri, student
, berfungsi sebagai referensi untuk setiap Student
di sumber, menyediakan akses anggota untuk setiap objek.
Jalankan kueri
Sekarang tulis perulangan foreach
yang menyebabkan kueri dijalankan. Setiap elemen dalam urutan yang dikembalikan diakses melalui variabel iterasi dalam perulangan foreach
. Jenis variabel ini Student
, dan jenis variabel kueri kompatibel, IEnumerable<Student>
. Setelah Anda menambahkan kode berikut, buat dan jalankan aplikasi untuk melihat hasilnya di jendela Konsol.
// Execute the query.
// var could be used here also.
foreach (Student student in studentQuery)
{
Console.WriteLine($"{student.Last}, {student.First}");
}
// Output:
// Omelchenko, Svetlana
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
Untuk menyempurnakan kueri lebih lanjut, Anda dapat menggabungkan beberapa kondisi Boolean dalam klausa where
. Kode berikut menambahkan kondisi sehingga kueri mengembalikan siswa yang skor pertamanya lebih dari 90 dan skor terakhirnya kurang dari 80. Klausa where
harus menyerupai kode berikut.
where student.Scores[0] > 90 && student.Scores[3] < 80
Coba klausa where
sebelumnya, atau eksperimen diri Anda dengan kondisi filter lainnya. Untuk informasi selengkapnya, lihat tempat klausa.
Mengurutkan hasil kueri
Lebih mudah untuk memindai hasilnya jika hasilnya dalam urutan tertentu. Anda dapat mengurutkan urutan yang dikembalikan oleh bidang apa pun yang dapat diakses di elemen sumber. Misalnya, klausul orderby
berikut mengurutkan hasil dalam urutan alfabet dari A hingga Z sesuai dengan nama keluarga setiap siswa. Tambahkan klausa orderby
berikut ke kueri Anda, tepat setelah pernyataan where
dan sebelum pernyataan select
:
orderby student.Last ascending
Sekarang ubah klausul orderby
sehingga mengurutkan hasil dalam urutan terbalik sesuai dengan skor pada pengujian pertama, dari skor tertinggi menjadi skor terendah.
orderby student.Scores[0] descending
Ubah string format WriteLine
sehingga Anda dapat melihat skornya:
Console.WriteLine($"{student.Last}, {student.First} {student.Scores[0]}");
Untuk informasi selengkapnya, lihat klausul urutan .
Mengelompokkan hasil
Pengelompokan adalah fitur yang kuat untuk ekspresi kueri. Kueri dengan klausul grup menghasilkan urutan grup, dan setiap grup itu sendiri berisi Key
dan urutan yang terdiri dari semua anggota grup tersebut. Kueri baru berikut mengelompokkan siswa dengan menggunakan huruf pertama nama keluarga mereka sebagai kunci.
IEnumerable<IGrouping<char, Student>> studentQuery =
from student in students
group student by student.Last[0];
Jenis kueri diubah. Sekarang menghasilkan urutan grup yang memiliki jenis char
sebagai kunci, dan urutan objek Student
. Kode dalam perulangan eksekusi foreach
juga harus berubah:
foreach (IGrouping<char, Student> studentGroup in studentQuery)
{
Console.WriteLine(studentGroup.Key);
foreach (Student student in studentGroup)
{
Console.WriteLine($" {student.Last}, {student.First}");
}
}
// Output:
// O
// Omelchenko, Svetlana
// O'Donnell, Claire
// M
// Mortensen, Sven
// G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
// F
// Fakhouri, Fadi
// Feng, Hanying
// T
// Tucker, Lance
// Tucker, Michael
// A
// Adams, Terry
// Z
// Zabokritski, Eugene
Jalankan aplikasi dan lihat hasilnya di jendela Konsol. Untuk informasi selengkapnya, lihat klausa grup .
Pengkodean eksplisit dari IEnumerables
ke IGroupings
dapat dengan cepat menjadi melelahkan. Tulis kueri yang sama dan perulangan foreach
dengan lebih mudah menggunakan var
. Kata kunci var
tidak mengubah jenis objek Anda; itu hanya menginstruksikan pengkompilasi untuk menyimpulkan jenis. Ubah jenis studentQuery
dan variabel iterasi group
menjadi var
dan jalankan ulang kueri. Dalam perulangan foreach
bagian dalam, variabel iterasi masih di ketik sebagai Student
, dan kueri berfungsi seperti sebelumnya. Ubah variabel perulangan student
menjadi var
dan jalankan kueri lagi. Anda melihat bahwa Anda mendapatkan hasil yang sama persis.
IEnumerable<IGrouping<char, Student>> studentQuery =
from student in students
group student by student.Last[0];
foreach (IGrouping<char, Student> studentGroup in studentQuery)
{
Console.WriteLine(studentGroup.Key);
foreach (Student student in studentGroup)
{
Console.WriteLine($" {student.Last}, {student.First}");
}
}
Untuk informasi selengkapnya tentang var
, lihat Variabel Lokal yang Di ketik secara Implisit.
Mengurutkan grup menurut nilai kuncinya
Grup dalam kueri sebelumnya tidak dalam urutan alfabet. Anda dapat memberikan klausa orderby
setelah klausa group
. Tetapi untuk menggunakan klausa orderby
, Anda terlebih dahulu memerlukan pengidentifikasi yang berfungsi sebagai referensi ke grup yang dibuat oleh klausa group
. Anda menyediakan pengidentifikasi dengan menggunakan kata kunci into
, sebagai berikut:
var studentQuery4 =
from student in students
group student by student.Last[0] into studentGroup
orderby studentGroup.Key
select studentGroup;
foreach (var groupOfStudents in studentQuery4)
{
Console.WriteLine(groupOfStudents.Key);
foreach (var student in groupOfStudents)
{
Console.WriteLine($" {student.Last}, {student.First}");
}
}
// Output:
//A
// Adams, Terry
//F
// Fakhouri, Fadi
// Feng, Hanying
//G
// Garcia, Cesar
// Garcia, Debra
// Garcia, Hugo
//M
// Mortensen, Sven
//O
// Omelchenko, Svetlana
// O'Donnell, Claire
//T
// Tucker, Lance
// Tucker, Michael
//Z
// Zabokritski, Eugene
Jalankan kueri ini, dan grup sekarang diurutkan dalam urutan alfabet.
Anda dapat menggunakan kata kunci let
untuk memperkenalkan pengidentifikasi untuk hasil dari ekspresi apa pun dalam ekspresi kueri. Pengidentifikasi ini bisa menjadi kenyamanan, seperti dalam contoh berikut. Ini juga dapat meningkatkan performa dengan menyimpan hasil ekspresi sehingga tidak perlu dihitung beberapa kali.
// This query returns those students whose
// first test score was higher than their
// average score.
var studentQuery5 =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where totalScore / 4 < student.Scores[0]
select $"{student.Last}, {student.First}";
foreach (string s in studentQuery5)
{
Console.WriteLine(s);
}
// Output:
// Omelchenko, Svetlana
// O'Donnell, Claire
// Mortensen, Sven
// Garcia, Cesar
// Fakhouri, Fadi
// Feng, Hanying
// Garcia, Hugo
// Adams, Terry
// Zabokritski, Eugene
// Tucker, Michael
Untuk informasi selengkapnya, lihat artikel tentang klausa let
.
Menggunakan sintaks metode dalam ekspresi kueri
Seperti yang dijelaskan dalam sintaks kueri dan Sintaks Metode di LINQ, beberapa operasi kueri hanya dapat diekspresikan dengan menggunakan sintaks metode. Kode berikut menghitung skor total untuk setiap Student
dalam urutan sumber, lalu memanggil metode Average()
pada hasil kueri tersebut untuk menghitung skor rata-rata kelas.
var studentQuery =
from student in students
let totalScore = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
select totalScore;
double averageScore = studentQuery.Average();
Console.WriteLine($"Class average score = {averageScore}");
// Output:
// Class average score = 334.166666666667
Untuk mengubah atau memproyeksikan dalam klausa pemilihan
Kueri umum untuk menghasilkan urutan yang elemennya berbeda dari elemen dalam urutan sumber. Hapus atau beri komentar pada kueri dan loop eksekusi sebelumnya, lalu gantikan dengan kode berikut. Kueri mengembalikan urutan string (tidak Students
), dan fakta ini tercermin dalam perulangan foreach
.
IEnumerable<string> studentQuery =
from student in students
where student.Last == "Garcia"
select student.First;
Console.WriteLine("The Garcias in the class are:");
foreach (string s in studentQuery)
{
Console.WriteLine(s);
}
// Output:
// The Garcias in the class are:
// Cesar
// Debra
// Hugo
Kode sebelumnya dalam panduan ini menunjukkan bahwa skor kelas rata-rata adalah sekitar 334. Untuk menghasilkan urutan Students
yang skor totalnya lebih besar dari rata-rata kelas, bersama dengan Student ID
, Anda dapat menggunakan tipe anonim dalam pernyataan select
.
var aboveAverageQuery =
from student in students
let x = student.Scores[0] + student.Scores[1] +
student.Scores[2] + student.Scores[3]
where x > averageScore
select new { id = student.ID, score = x };
foreach (var item in aboveAverageQuery)
{
Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score);
}
// Output:
// Student ID: 113, Score: 338
// Student ID: 114, Score: 353
// Student ID: 116, Score: 369
// Student ID: 117, Score: 352
// Student ID: 118, Score: 343
// Student ID: 120, Score: 341
// Student ID: 122, Score: 368