dari klausul (Referensi C#)
Ekspresi kueri harus diawali dengan klausul from
. Selain itu, ekspresi kueri dapat berisi sub-kueri, yang juga diawali dengan klausul from
. Klausul from
menentukan hal berikut:
Sumber data tempat kueri atau sub-kueri akan dijalankan.
Variabel rentang lokal yang mewakili setiap elemen dalam urutan sumber.
Baik variabel rentang maupun sumber data dijeniskan dengan tepat. Sumber data yang direferensikan dalam klausul from
harus memiliki jenis IEnumerable, IEnumerable<T>, atau jenis turunan seperti IQueryable<T>.
Dalam contoh berikut, numbers
adalah sumber data dan num
adalah variabel rentang. Perhatikan bahwa kedua variabel dijeniskan dengan tepat meskipun kata kunci var digunakan.
class LowNums
{
static void Main()
{
// A simple data source.
int[] numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
// Create the query.
// lowNums is an IEnumerable<int>
var lowNums = from num in numbers
where num < 5
select num;
// Execute the query.
foreach (int i in lowNums)
{
Console.Write(i + " ");
}
}
}
// Output: 4 1 3 2 0
Variabel rentang
Pengompilasi menyimpulkan jenis variabel rentang saat sumber data mengimplementasikan IEnumerable<T>. Misalnya, jika sumber memiliki jenis IEnumerable<Customer>
, maka variabel rentang disimpulkan menjadi Customer
. Satu-satunya waktu saat Anda harus menentukan jenis secara eksplisit adalah ketika sumber merupakan jenis IEnumerable
non-generik seperti ArrayList. Untuk informasi selengkapnya, lihat Cara mengkueri ArrayList dengan LINQ.
Dalam contoh sebelumnya num
disimpulkan berjenis int
. Karena variabel rentang dijeniskan dengan tepat, Anda dapat memanggil metode di atasnya atau menggunakannya di operasi lain. Misalnya, alih-alih menulis select num
, Anda dapat menulis select num.ToString()
untuk menyebabkan ekspresi kueri mengembalikan urutan string alih-alih bilangan bulat. Atau Anda dapat menulis select num + 10
untuk menyebabkan ekspresi mengembalikan urutan 14, 11, 13, 12, 10. Untuk informasi selengkapnya, lihat klausul pilihan.
Variabel rentang mirip dengan variabel perulangan dalam pernyataan foreach kecuali untuk satu perbedaan yang sangat penting: variabel rentang tidak pernah benar-benar menyimpan data dari sumbernya. Ini hanya kenyamanan sintaktis yang memungkinkan kueri untuk menggambarkan apa yang akan terjadi ketika kueri dijalankan. Untuk informasi selengkapnya, lihat Pengantar Kueri LINQ (C#).
Klausul from gabungan
Dalam beberapa kasus, setiap elemen dalam urutan sumber dapat berupa urutan itu sendiri atau berisi urutan. Misalnya, sumber data Anda mungkin merupakan IEnumerable<Student>
tempat setiap objek siswa dalam urutan berisi daftar skor pengujian. Untuk mengakses daftar yang lebih dalam di dalam setiap elemen Student
, Anda dapat menggunakan klausul from
gabungan. Teknik ini mirip dengan menggunakan pernyataan foreach berlapis. Anda dapat menambahkan klausul where atau orderby ke salah satu klausul from
untuk memfilter hasilnya. Contoh berikut menunjukkan urutan objek Student
, masing-masing berisi bilangan bulat List
yang lebih dalam yang mewakili skor pengujian. Untuk mengakses daftar yang lebih dalam, gunakan klausul from
gabungan. Anda dapat menyisipkan klausul di antara kedua klausul from
jika perlu.
class CompoundFrom
{
// The element type of the data source.
public class Student
{
public required string LastName { get; init; }
public required List<int> Scores {get; init;}
}
static void Main()
{
// Use a collection initializer to create the data source. Note that
// each element in the list contains an inner sequence of scores.
List<Student> students =
[
new Student {LastName="Omelchenko", Scores= [97, 72, 81, 60]},
new Student {LastName="O'Donnell", Scores= [75, 84, 91, 39]},
new Student {LastName="Mortensen", Scores= [88, 94, 65, 85]},
new Student {LastName="Garcia", Scores= [97, 89, 85, 82]},
new Student {LastName="Beebe", Scores= [35, 72, 91, 70]}
];
// Use a compound from to access the inner sequence within each element.
// Note the similarity to a nested foreach statement.
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };
// Execute the queries.
Console.WriteLine("scoreQuery:");
// Rest the mouse pointer on scoreQuery in the following line to
// see its type. The type is IEnumerable<'a>, where 'a is an
// anonymous type defined as new {string Last, int score}. That is,
// each instance of this anonymous type has two members, a string
// (Last) and an int (score).
foreach (var student in scoreQuery)
{
Console.WriteLine("{0} Score: {1}", student.Last, student.score);
}
}
}
/*
scoreQuery:
Omelchenko Score: 97
O'Donnell Score: 91
Mortensen Score: 94
Garcia Score: 97
Beebe Score: 91
*/
Menggunakan Beberapa Klausul from untuk Melakukan Penggabungan
Klausul from
gabungan digunakan untuk mengakses koleksi yang lebih dalam di dalam satu sumber data. Namun, kueri juga dapat berisi beberapa klausul from
yang menghasilkan kueri tambahan dari sumber data independen. Teknik ini memungkinkan Anda untuk melakukan jenis operasi gabungan tertentu yang tidak memungkinkan dengan menggunakan gabungkan klausul.
Contoh berikut menunjukkan bagaimana dua klausul from
dapat digunakan untuk membentuk gabungan silang lengkap dari dua sumber data.
class CompoundFrom2
{
static void Main()
{
char[] upperCase = ['A', 'B', 'C'];
char[] lowerCase = ['x', 'y', 'z'];
// The type of joinQuery1 is IEnumerable<'a>, where 'a
// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery1 =
from upper in upperCase
from lower in lowerCase
select new { upper, lower };
// The type of joinQuery2 is IEnumerable<'a>, where 'a
// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery2 =
from lower in lowerCase
where lower != 'x'
from upper in upperCase
select new { lower, upper };
// Execute the queries.
Console.WriteLine("Cross join:");
// Rest the mouse pointer on joinQuery1 to verify its type.
foreach (var pair in joinQuery1)
{
Console.WriteLine("{0} is matched to {1}", pair.upper, pair.lower);
}
Console.WriteLine("Filtered non-equijoin:");
// Rest the mouse pointer over joinQuery2 to verify its type.
foreach (var pair in joinQuery2)
{
Console.WriteLine("{0} is matched to {1}", pair.lower, pair.upper);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Cross join:
A is matched to x
A is matched to y
A is matched to z
B is matched to x
B is matched to y
B is matched to z
C is matched to x
C is matched to y
C is matched to z
Filtered non-equijoin:
y is matched to A
y is matched to B
y is matched to C
z is matched to A
z is matched to B
z is matched to C
*/
Untuk informasi selengkapnya tentang operasi gabungan yang menggunakan beberapa klausul from
, lihat Melakukan gabungan kiri luar.