ทำความรู้จัก LINQ [ตอน1]

Home Page  |   รายการบทความ   |   ลิงค์ที่เกี่ยวข้อง   |   laploy.com  |  เกี่ยวกับผู้เขียน

ตัวอย่างเนื้อหาของหนังสือ เรีนรู้ด้วยตนเอง LINQ

    [ตอน1]

 

ซอฟต์แวร์คือการผสมผสานระหว่างโค้ดและข้อมูล การพัฒนาซอฟต์แวร์คือการเขียนโค้ดเพื่อดำเนินการกับข้อมูล ในการเขียนโค้ดมีภาษาโปรแกรมให้เลือกจำนวนมาก ท่านจะเลือกภาษาอะไรขึ้นอยู่กับปัจจัยต่างๆ หลายประการ อาทิ ลักษณะของงานที่จะนำไปใช้ ความถนัดของท่านหรือทีมผู้พัฒนา ระบบปฏิบัติการที่จะนำไปใช้ หรือนโยบายที่บริษัทหรือลูกค้ากำหนด แต่ไม่ว่าจะใช้ภาษาอะไรลงท้ายก็ต้องเขียนโค้ดซึ่งเกี่ยวข้องกับข้อมูลอยู่ดี โดยข้อมูลอาจอยู่ในแหล่งต่างๆ หลายแบบ อาทิ เป็นไฟล์ในดิสก์ เป็นตารางในฐานข้อมูล เป็นเอกสารแบบ XML ที่มาจากเว็บ หรือบ่อยครั้งที่ในงานๆ เดียวต้องพาดพิงแหล่งข้อมูลทุกแบบที่ว่ามานี้ผสมกัน กล่าวโดยถึงที่สุดแล้วไม่ว่าจะพัฒนาซอฟต์แวร์โครงการไหนมักหนีไม่พ้นจะต้องข้องเกี่ยวกับการจัดการข้อมูลในรูปแบบใดรูปแบบหนึ่งเสมอ

เมื่อท่านพัฒนาซอฟต์แวร์ท่านย่อมคาดหวังว่าสภาพแวดล้อมจะเอื้ออำนวยให้ท่านจัดการข้อมูลได้ง่าย คือมีเครื่องมือ หรือมีตัวช่วย หรือมีไลบรารี ที่จะทำให้ท่านเข้าถึงแหล่งข้อมูลได้ง่าย ไม่ต้องพัฒนาสิ่งพื้นฐานเอาเองจากศูนย์ทั้งหมด หากท่านพัฒนาซอฟต์แวร์บนดอตเน็ตเฟรมเวิร์ค (Microsoft .NET Framework ย่อ NETFX) ท่านย่อมสบายใจได้ เพราะ NETFX จัดเตรียมกลไกที่เกี่ยวข้องกับการจัดการข้อมูลมาให้อย่างอุดมตั้งแต่เวอร์ชันแรก และยิ่งไปกว่านั้นในเวอร์ชัน 3.5 NETFX ได้จัดเตรียม LINQ ซึ่งช่วยผสานการจัดการข้อมูลเข้ากับภาษา C# ได้ใกล้ชิดขึ้นจนเป็นเนื้อเดียวกัน

ก่อนที่จะมุ่งเข้าสู่เนื้อหาที่เป็นรายละเอียดต่างๆ เกี่ยวกับ LINQ ในบทนี้ท่านจะได้เห็นภาพมุมกว้างโดยทั่วๆ ไปของ LINQ เสียก่อน เพื่อให้รู้ว่าอะไรอยู่ที่ใด ซึ่งจะช่วยให้ท่านมองเห็นความสัมพันธ์ระหว่างส่วนต่างๆ ได้ชัดขึ้นเมื่อท่านเรียนถึงเนื้อหาส่วนรายละเอียด

แนะนำ LINQ เบื้องต้น
เมื่อท่านพัฒนาซอฟต์แวร์ด้วยภาษา C# ต้องมีจุดใดจุดหนึ่งในโปรแกรมที่ท่านจำเป็นต้องนำข้อมูลในออพเจ็กต์บันทึกลงไว้ในฐานข้อมูล กระทำคิวรีต่อฐานข้อมูล และนำข้อมูลจากฐานข้อมูลมาใส่ไว้ในออพเจ็กต์อีกรอบหนึ่ง ยกตัวอย่างเช่นท่านทำเว็บไซต์ขายสินค้า ท่านรับข้อมูลการสั่งซื้อมาเก็บไว้ในออพเจ็กต์ (หรือออพเจ็กต์คอลเลคชัน เช่นลิสต์ หรือดาต้ากริตวิว) จากนั้นนำข้อมูลนี้บันทึกลงสู่ตารางในฐานข้อมูลไมโครซอฟต์ SQL เซอฟเวอร์ 2008 (Microsoft SQL Server version 2008 ย่อ SQL2008) ในสมัยที่ยังไม่มี LINQ ท่านอาจทำทุกอย่างผ่านทางการเชื่อมต่อตามลัทธิ ADO.NET จากนั้นกระทำคิวรีกับฐานข้อมูลเพื่อดึงข้อมูลจากตารางต่างๆ มาผสมกันให้ได้เป็นธุรกรรมที่สมบูรณ์ แล้วนำข้อมูลสุดท้ายมาใส่ในออพเจ็กต์ (หรือออพเจ็กต์คอลเลคชัน เช่นดาต้าเทเบิล หรือดาต้ากริตวิว)เพื่อนำไปฉายแสดงให้ผู้ใช้ได้ดูชมบนหน้าเว็บ

โชคดีที่ภาษา C# สนับสนุน OOP อย่างถึงที่สุด ทำให้ท่านพัฒนางานด้วยหลักการ OOP ได้ง่ายและได้อย่างเต็มที่ แต่โชคร้ายที่ตัวจัดการฐานข้อมูลสัมพันธ์ (Relational Database Management System ย่อ RDBMS) อย่าง SQL2008 ไม่เป็นเช่นนั้น นักพัฒนาพยายามทำฐานข้อมูลให้เป็นออพเจ็กต์โดยห่อหุ้มฐานข้อมูลไว้ในคลาส (Object/Relational Mapping ย่อ O/RM) โดยใช้เครื่องมือเท่าที่มีอยู่ในขณะนั้น ยกตัวอย่างเช่นบทที่ 11 ในหนังสือ “เรียนรู้ด้วยตนเอง OOP C# ASP.NET” (ISBN 13:978-974-212-598-1 ย่อ LOYOOP) ผู้เขียนสาธิตวิธีทำเช่นนี้

สภาพการก่อนมี LINQ
การทำ O/RM ใน NETFX เวอร์ชันก่อน 3 แม้จะทำได้และใช้งานได้จริงแต่ก็ไม่สะดวก และมีจุดอ่อนที่ไม่สามารถนำโค้ดกลับมาใช้ใหม่ได้ซึ่งถือว่าเป็นเรื่องใหญ่ เพราะ Code Reusable คือหัวใจสำคัญของการเขียนโปรแกรมวัตถุวิธี หากจะแก้ให้ตรงประเด็นก็ต้องเปลี่ยนไปใช้ฐานข้อมูลแบบ OOP (Object-oriented Database Management System ย่อ ODBMS) โชคร้ายที่ในทางปฏิบัติทำไม่ได้ เพราะ ODBMS ไม่ได้รับความนิยม หน่วยงานต่างๆ ล้วนแล้วแต่ใช้ฐานข้อมูลแบบ RDBMS เช่น SQL2008, ออราเคิล PostgreSQL, DB2, MySQL ฯลฯ ด้วยกันทั้งสิ้น

บริษัทไมโครซอฟต์รู้ว่าแนวทางของคอดด์นั้นดีเยี่ยมและผู้คนจะไม่เปลี่ยนใจไปจาก RDBMS ได้ง่ายนัก จึงจัดตั้งหน่วยงานขึ้นเพื่อค้นคว้าหาวิธีขจัดความยุ่งยากทางเทคนิคของการทำงานร่วมกันระหว่างฐานข้อมูลกับแอพลิเกชันที่พัฒนาด้วยภาษา C# ผลลัพธ์ที่ได้คือ LINQ ซึ่งช่วยให้การทำ OR/M ง่ายขึ้น โดยเฉพาะอย่างยิ่งหากท่านพัฒนาโดยอาศัย Visual Studio 2008 (VS2008) ท่านจะสามารถทำ OR/M ได้โดยไม่ต้องเขียนโค้ดแม้แต่บรรทัดเดียว เพียงลากและหยอด VS2008 จะผลิตโค้ดที่จำเป็นให้ได้อย่างครบถ้วน

ความคิดดั้งเดิมของ LINQ คือต้องการให้การพัฒนาโปรแกรมภาษา C# ทำงานกับฐานข้อมูล SQL2008 ได้ง่ายขึ้นและเป็น OOP มากขึ้น เรียกว่า LINQ to ADO.NET แต่ต่อมาความคิดเกี่ยวกับ LINQ เริ่มคลี่คลายและขยายเป้าหมายออกไปกว้างกว่าตอนต้นมาก สุดท้าย LINQ กลายเป็นภาษาอเนกประสงค์ทำงานร่วมกับแหล่งข้อมูลได้สารพัด ยกตัวอย่างเช่น LINQ ที่ทำงานกับ SQL2008 เรียกว่า LINQ to SQL ส่วน LINQ ที่ทำงานกับแฟ้มแบบ XML เรียกว่า LINQ to XML และ LINQ ที่ทำงานกับออพเจ็กต์ เรียกว่า LINQ to Objects

โปรแกรมจัดการฐานข้อมูลวัตถุวิธีหรือ ODBMS ไม่ได้รับความนิยม หน่วยงานต่างๆ ล้วนแล้วแต่ใช้ฐานข้อมูลแบบ RDBMS ภาพนี้คือโปรแกรม IBM DB2 Cube View 8.2

 

มหาเอกะทฤษฏี

ขณะที่สตีเฟน ฮอว์กินส์ กำลังหาทางรวมทฤษฏีทั้งหมดเข้าด้วยกันให้เป็นทฤษฏีเดียวที่อธิบายได้ทุกอย่างในเอกภพหรือ มหาเอกะทฤษฏี (Grand Unified Theory ย่อ GUT) แต่ยังหาทางทำไม่สำเร็จ ทีมงาน LINQ กลับประสบความสำเร็จในการทำให้ LINQ สามารถทำงานร่วมกับแหล่งข้อมูลอะไรก็ได้ (Unified Data Source ย่อ UDS) ดังนั้นท่านจึงสามารถเขียนโค้ด (ที่มีซินแท็กซ์คล้ายๆ ภาษา SQL) เพื่อคิวรีข้อมูลภายใน SQL2008 ในลิสต์หรือแม้กระทั่งในแฟ้มข้อมูลตัวหนังสือได้โดยใช้วิธีการเดียวกัน

เนื่องจากคิวรีที่ว่านี้เป็นภาษาที่กลืนเข้าเป็นเนื้อเดียวกันกับภาษา C# จึงเป็นที่มาของชื่อ LINQ (อ่านว่าลิ้งค์เหมือน Link) ย่อมาจากคำว่า Language INtegrated Query หมายถึงคิวรีที่ถูกบูรณาเข้ากับภาษาเขียนโปรแกรม (ขณะนี้สนับสนุนเฉพาะภาษา C# 3.0 แล VB.NET 9.0 ขึ้นไปเท่านั้น) คำว่าบูรณาการในที่นี้หมายถึงผสานเข้าด้วยกันอย่างไม่มีรอยต่อ เหมือนเป็นภาษาซ้อนในภาษา ยกตัวอย่างเช่นสมมุติว่าท่านต้องการคิวรีข้อมูลในตาราง Production.Product ของฐานข้อมูล AdventureWorks2008 หากทำในโปรแกรม Microsoft SQL Server Management Studio (SSMS) จะมีคิวรีและได้ผลลัพธ์อย่างที่เห็นในภาพ 1-2 หากเขียนเป็นโปรแกรมภาษา C# และเชื่อมต่อฐานข้อมูลด้วย ADO.NET โค้ดจะเป็นอย่างที่เห็นในภาพ 1-3 และผลลัพธ์เป็นอย่างภาพ 1-4

ภาพ 1-2: การคิวรีตาราง Production.Product ในฐานข้อมูล AdventureWorks2008 ด้วยภาษา T-SQL

ภาพ 1-3: โค้ดภาษา C# แสดงตัวอย่างแสดงวิธีคิวรีข้อมูลในตาราง Categories ของฐานข้อมูล AdventureWorks2008 โดยใช้สถาปัตยกรรม ADO.NET

ภาพ 1-4: ผลลัพธ์จากการทำงานของโปรแกรมในภาพ ado sample code

 

โปรดสังเกตว่าโค้ดในภาพ 1-3 ส่วนที่เป็นคิวรีคือบรรทัดที่ 17 และ 18 ซึ่งอยู่ในสภาพสตริง ภาวะเช่นนี้ไม่ถือว่าคิวรีถูกบูรณาการเข้ากับภาษา C# เพราะตัวแปลภาษา C# และ CLR (Common Language Runtime) ไม่รับรู้ว่าสตริงนี้เป็นคิวรี ในทางตรงกันข้าม ตัวแปรภาษา C# จะไม่แปลคิวรีนี้และจะไม่ตรวจสอบว่าคิวรีมีไวยากรณ์ถูกต้องหรือไม่ และ CLR ก็จะไม่ให้หลักประกันในการทำงานและไม่อาจแสดงข้อความรันทามน์เออเรอร์ (Runtime Error Message ย่อ REM) ที่ถูกต้องตรงกับความเป็นจริงได้

ต่อไปลองมาดูตัวอย่างโค้ดภาษา C# ซึ่งทำหน้าที่เดียวกันและให้ผลลัพธ์เดียวกันทุกอย่าง แต่ใช้สถาปัตยกรรม LINQ บาง โค้ดเป็นอย่างที่เห็นในภาพ 1-5 คำว่า DataClasses1DataContext ในบรรทัดที่ 40 คือ O/RM ที่ผู้เขียนสร้างโดยการลากและหยอดไว้ก่อนแล้ว ส่วนที่เป็นคิวรีคือบรรทัดที่ 43 และ 44 โค้ดสองบรรทัดนี้เป็นส่วนหนึ่งของภาษา C# ดังนั้นตัวแปลภาษา C# จึงสามารถตรวจสอบได้ว่าเขียนผิดไวยากรณ์หรือไม่ และ CLR จะสามารถตรวจสอบความถูกต้องของไทป์ได้จึงแสดง RE ที่ถูกต้องตอนรันได้ ภาวะเช่นนี้ทำให้ LINQ เป็นคิวรีที่ถูกบูรณาเข้ากับภาษาเขียนโปรแกรมได้กลมกลืนเป็นเนื้อเดียวกัน

 

ภาพ 1-5: โค้ดภาษา C# ซึ่งทำหน้าที่เดียวกันและให้ผลลัพธ์เดียวกันทุกอย่าง แต่ใช้สถาปัตยกรรม LINQ

กรุณาติดตามตอนต่อไป

Advertisements

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out /  เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out /  เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out /  เปลี่ยนแปลง )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: