Cara Menggunakan Dynamic Where pada LINQ

Ketika menggunakan query sql, kita dapat membuat query yang dynamic sesuai dengan kondisi mana yang terpenuhi. Misal bila kita ingin mengambil data Produk, kita bisa melakukan filter sesuai dengan kolom yang akan dicari, bisa berdasarkan nama produk, kategori, supplier, atau harga. Contoh kodenya, biasanya yang kulakukan adalah melakukan String Concat atau String Builder. Ini contoh yang pakai string concat.

Dim FilterBy As String = "nama"
Dim WhereString = ""

If (FilterBy = "nama") Then
    WhereString = " ProductName LIKE '%berry%'"
ElseIf (FilterBy = "kategori") Then
    WhereString = " CategoryID = 2"
End If

Dim QueryString = "SELECT * FROM Products WHERE " & WhereString

Nah, kalau pakai LINQ, bagaimana caranya ya? Kan query LINQ gak bisa ditulis secara dinamis?

Reuseable Query

Query LINQ memang tidak dapat ditulis secara dinamis seperti query string SQL. Namun, di LINQ ada fitur Reuseable Query yang bisa kita gunakan untuk mengakali masalah ini. Berikut contoh query LINQ untuk mengambil data sesuai dengan query di atas.

' Hasil: SELECT * FROM Products
Dim getAllProducts = From p In Products
                     Select p

' Hasil: SELECT * FROM Products WHERE ProductName LIKE '%berry%'
Dim getProductByName = From p In getAllProducts
                       Where p.ProductName.Contains("berry")
                       Select p

' Hasil: SELECT * FROM Products WHERE CategoryID = 2
Dim getProductByCategory = From p In getAllProducts
                           Where p.CategoryID = 2
                           Select p

JOIN Table

Btw, reuseable query ini bisa juga digunakan pada query yang menggunakan klausa join, projection, orderby, dll. Nih contohnya.

' SELECT [t0].[ProductName], [t1].[CategoryName]
' FROM [Products] AS [t0]
' INNER JOIN [Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])
Dim getAllProducts = From p In Products
                     Join c In Categories On p.CategoryID Equals c.CategoryID
                     Select New With {p.ProductName, c.CategoryName}

' SELECT [t0].[ProductName], [t1].[CategoryName]
' FROM [Products] AS [t0]
' INNER JOIN [Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])
' WHERE [t0].[ProductName] LIKE '%berry'
Dim getProductByName = From p In getAllProducts
                       Where p.ProductName.Contains("berry")
                       Select p

2 Kali Query?

Owh ya, pada contoh di atas, kusertakan query string sql yang digenerate oleh Entity Framework (copy-paste dari LINQPad) untuk tiap query LINQ. Meski pada query getProductByName dan getProductByCategory kita melakukan query dari query getAllProducts (reuseable query), namun query sql yang digenerate oleh Entity Framework sudah sangat cerdas dan tepat.

Dan salah satu hal penting yang perlu diingat, query LINQ tidak akan dieksekusi sampai benar-benar dibutuhkan. Jadi bila kita hanya melakukan query database menggunakan query LINQ getProductByName, maka query getAllProducts tidak akan pernah dieksekusi.

Maaf, kata-katanya agak membingungkan, hehe.

Semoga bermanfaat. Amin..

Tetap Sehat, Tetap Semangat, agar dapat Tetap dalam Perdjoeangan!!

Hartadi

I’m a Passionate Programmer ;)

Leave a Reply