Tuesday, 9 June 2015

Mengenal LINQ Pada Framework Microsoft .NET (dan Class List)

LINQ atau Language INtegrated Query merupakan sebuah komponen pada platform Microsoft .NET. Dengan adanya LINQ, bahasa pemrograman yang digunakan pada framework Microsoft .NET memiliki kemampuan native query terhadap data. LINQ sendiri sudah mulai ditambahkan pada framework .NET sejak versi 3.0 dan VB 9.0.
Seiring dengan meningkatnya kompleksitas dalam komputasi dan manipulasi data, kebutuhan akan melakukan native query di dalam bahasa pemrograman pun meningkat. Pada umumnya kita mengenal istilah query ketika bermain-main dengan database, SQL, bahasa tersebut biasanya identik dengan istilah query. Namun perlu diketahui bahwa query sendiri adalah suatu metode pengambilan data terlepas dari sumbernya yang bisa berupa database, file teks, atau data di dalam memory. Lalu mengapa LINQ menjadi hal yang menarik bahkan mungkin sebagian programmer .NET tidak terpisahkan dari LINQ?
Jawabnya adalah fleksibilitas dalam manipulasi data. Bayangkan apabila variable array yang biasa Anda gunakan, diperlakukan seperti halnya tabel pada database, pengambilan data dapat dilakukan menggunakan query yang dapat dikembangkan sesuai dengan spesifikasi yang Anda inginkan, meminimalkan baris kode dalam melakukan sorting data serta menghindari dilakukannya iterasi atau looping ketika hendak mencari suatu data spesifik. Kedengarannya luar biasa bukan? Namun Anda tidak akan percaya sebelum melihat dan mencobanya.
Sebelum kita melihat contoh penerapannya di dalam kode program, perlu juga diketahui bahwa LINQ, layaknya query SQL, mengenal operasi standar seperti select, where, selectmany, distinct, min/max/average, sum, join, dan lain-lain. Lalu Anda juga perlu mengetahui class List<T> pada framework .NET. Class List<T> merupakan array, namun berbeda dengan array tradisional yang panjangnya tidak dapat berubah secara dinamis, List<T> memiliki panjang yang dinamis sesuai dengan data yang ada di dalamnya. Class List<T> berada di dalam namespace System.Collections.Generic. Ketika mendeklarasikan instance List, Anda harus mendefinisikan tipenya sebab List dianggap sebagai tipe generic. Sebagai contoh, ketika Anda hendak membuat List yang berisi nilai integer, maka bentuk deklarasinya adalah sebagai berikut:
1
List<int> listInteger = new List<int>();
 Perhatikan bahwa "T" pada List<T> menunjukkan tipe data dari anggota atau element yang terkandung di dalam List. Dengan kata lain, Anda juga dapat membuat List dengan tipe string dengan cara yang sama:
1
List<string> listString = new List<string>();
 Hanya sebatas tipe data primitif? Tidak. Contoh berikut adalah List yang berisi class yang penulis buat sendiri:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Buah
    {
        private string namaBuah = "";
        private string warnaBuah = "";
         
        public Buah(string namaBuah = "", string warnaBuah = "")
        {
            this.namaBuah = namaBuah;
            this.warnaBuah = warnaBuah;
        }
        public string Nama { get { return namaBuah; } set { namaBuah = value; } }
        public string Warna { get { return warnaBuah; } set { warnaBuah = value; } }
    }
List<Buah> listBuah = new List<Buah>();
 Lalu pertanyaan selanjutnya adalah, bagaimana cara mengisi suatu List dengan element-element yang Anda kehendaki? Secara umum, untuk mengisi atau menambahkan element pada List adalah dengan memanggil method List<T>.Add(item), di mana tipe data item adalah T. Contoh di bawah ini akan memperjelas penggunaan method List<T>.Add(item).
Untuk mengisi List<int>, tentu saja element yang dapat dimasukkan adalah berupa integer. Maka kode yang digunakan adalah:
1
2
3
4
5
6
7
8
9
List<int> listInteger = new List<int>();
//Menambahkan nilai integer ke dalam listInteger
listInteger.Add(20);
listInteger.Add(11);
//Element yang ditambahkan bisa juga berupa variable lain
int i = 8;
listInteger.Add(i);
 Lalu di atas saya memberi contoh class Buah yang saya buat sendiri. Saya juga menyatakan bahwa tipe data List bisa berupa class yang saya buat sendiri. Pada contoh class Buah, ketika Anda membuat listBuah, didefinisikan bahwa element atau anggota dari listBuah merupakan instance dari class Buah, oleh sebab itu listBuah hanya boleh diisi dengan variable yang merupakan instance dari class Buah. Contohnya adalah sebagai berikut:
1
2
3
4
listBuah.Add(new Buah("Apel", "Merah"));
listBuah.Add(new Buah("Jeruk", "Oranye"));
listBuah.Add(new Buah("Anggur", "Ungu"));
listBuah.Add(new Buah("Semangka", "Hijau"));
Seperti halnya sebuah array, tentu saja Anda juga seringkali perlu mengakses data yang disimpan di dalamnya. Apabila Anda memperlakukan List sebagaimana layaknya sebuah array konvensional, seringkali Anda perlu melakukan iterasi untuk mengakses element tertentu. Contoh iterasi untuk terhadap semua isi dari listBuah adalah sebagai berikut:
1
2
3
4
5
6
7
8
9
10
11
foreach (Buah buah in listBuah)
                {
                    //Lakukan sesuatu terhadap variable "buah"
                }
//atau
for (int i = 0; i < listBuah.Count; i++)
                {
                    //Lakukan sesuatu terhadap "listBuah[i]"
                }
 Pada kode di atas, List terlihat tidak ubahnya array konvensional. Tetapi tunggu sampai kita menggunakan LINQ untuk melakukan pengambilan data. Lihat contoh berikut:
1
2
3
var urutanBuah = from p in listBuah
                                orderby p.Nama
                                select p;
 Kode di atas akan mengisi variable sementara bernama urutanBuah, di mana isinya adalah element-element List listBuah yang telah diurutkan berdasarkan nama. Berikut adalah contoh lain untuk mengambil element-element buah dengan warna tertentu, misalnya ungu:
1
List<Buah> seleksiBuah = listBuah.Where(p => p.Warna.Equals("ungu").ToList();
 Pada kode di atas, semua element listBuah yang memiliki attribute "Warna" ungu akan diisikan ke dalam List baru bernama seleksiBuah. Perhatikan juga bahwa tipe seleksiBuah adalah Buah, sama dengan listBuah.
Berikut adalah listing kode lengkap yang digunakan di dalam artikel ini:
File: Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ContohLINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
            Console.ReadLine();
        }
        private List<Buah> listBuah;
        public Program()
        {
            listBuah = new List<Buah>();
            Console.WriteLine("Buat daftar buah-buahan:");
            Console.WriteLine("===================================");
            BuatlistBuah();
            UrutkanBuah();
            UrutkanBuah(1);
        }
        private void BuatlistBuah()
        {
            Console.WriteLine("Buah: Apel; Warna: Merah");
            listBuah.Add(new Buah("Apel", "Merah"));
            Console.WriteLine("Buah: Jeruk; Warna: Oranye");
            listBuah.Add(new Buah("Jeruk", "Oranye"));
            Console.WriteLine("Buah: Anggur; Warna: Ungu");
            listBuah.Add(new Buah("Anggur", "Ungu"));
            Console.WriteLine("Buah: Semangka; Warna: Hijau");
            listBuah.Add(new Buah("Semangka", "Hijau"));
            Console.WriteLine("===================================");
        }
        /// <summary>
        /// Contoh Sorting dengan LINQ
        /// </summary>
        /// <param name="param">param = 0, urut berdasarkan nama buah. param = 1, urut berdasarkan warna buah</param>
        private void UrutkanBuah(int param = 0)
        {
            if (param == 0)
            {
                Console.WriteLine("Buah Diurutkan Berdasarkan Nama");
                Console.WriteLine("===================================");
                var urutanBuah = from p in listBuah
                                 orderby p.Nama
                                 select p;
                foreach (Buah buah in urutanBuah.ToList())
                {
                    Console.WriteLine("Nama: " + buah.Nama + "; Warna: " + buah.Warna);
                }
                 
            }
            else if (param == 1)
            {
                Console.WriteLine("Buah Diurutkan Berdasarkan Warna");
                Console.WriteLine("===================================");
                var urutanBuah = from p in listBuah
                                 orderby p.Warna
                                 select p;
                foreach (Buah buah in urutanBuah.ToList())
                {
                    Console.WriteLine("Nama: " + buah.Nama + "; Warna: " + buah.Warna);
                }
            }
            else
            {
                throw new ArgumentException("Parameter tidak valid");
            }
            Console.WriteLine("===================================\n\n");
            Console.WriteLine("Cari Buah Berwarna Ungu");
            CariBuahBerdasarkanWarna("ungu");
        }
        private void CariBuahBerdasarkanWarna(string warna = "")
        {
            if (!string.IsNullOrEmpty(warna))
            {
                List<Buah> seleksiBuah = listBuah.Where(p => p.Warna.Equals(warna, StringComparison.InvariantCultureIgnoreCase)).ToList();
                if (seleksiBuah.Count > 0)
                {
                    foreach (Buah buah in seleksiBuah)
                    {
                        Console.WriteLine(buah.Nama);
                    }
                }
                else
                {
                    Console.WriteLine("Buah berwarna " + warna + " tidak ditemukan.");
                }
            }
            else
            {
                throw new ArgumentException("Parameter tidak valid");
            }
        }
    }
    public class Buah
    {
        private string namaBuah = "";
        private string warnaBuah = "";
         
        public Buah(string namaBuah = "", string warnaBuah = "")
        {
            this.namaBuah = namaBuah;
            this.warnaBuah = warnaBuah;
        }
        public string Nama { get { return namaBuah; } set { namaBuah = value; } }
        public string Warna { get { return warnaBuah; } set { warnaBuah = value; } }
    }
}

Setelah melihat contoh-contoh di atas, maka dapat disimpulkan bahwa LINQ memberikan fleksibilitas lebih dalam melakukan pemrograman. Class List<T> juga turut mendukung fleksibilitas LINQ dengan menyediakan tempat penampungan berupa array dinamis yang tipe datanya dapat disesuaikan dengan hasil query LINQ. Hal menarik lainnya adalah, selama ini banyak orang yang berpendapat bahwa query identik dengan database, namun artikel ini menceritakan tentang query dan tidak menggunakan database tertentu.
 Saya berharap artikel ini dapat bermanfaat bagi pembaca, terutama programmer .NET yang belum pernah menggunakan LINQ dan ingin menggunakannya pada kesempatan mendatang. Jangan lupa juga, LINQ hanya tersedia pada framework .NET 3.0 ke atas.

No comments:

Post a Comment