ทำความรู้จัก LINQ [ตอน1]
กันยายน 22, 2009 ใส่ความเห็น
ตัวอย่างเนื้อหาของหนังสือ เรีนรู้ด้วยตนเอง LINQ
ซอฟต์แวร์คือการผสมผสานระหว่างโค้ดและข้อมูล การพัฒนาซอฟต์แวร์คือการเขียนโค้ดเพื่อดำเนินการกับข้อมูล ในการเขียนโค้ดมีภาษาโปรแกรมให้เลือกจำนวนมาก ท่านจะเลือกภาษาอะไรขึ้นอยู่กับปัจจัยต่างๆ หลายประการ อาทิ ลักษณะของงานที่จะนำไปใช้ ความถนัดของท่านหรือทีมผู้พัฒนา ระบบปฏิบัติการที่จะนำไปใช้ หรือนโยบายที่บริษัทหรือลูกค้ากำหนด แต่ไม่ว่าจะใช้ภาษาอะไรลงท้ายก็ต้องเขียนโค้ดซึ่งเกี่ยวข้องกับข้อมูลอยู่ดี โดยข้อมูลอาจอยู่ในแหล่งต่างๆ หลายแบบ อาทิ เป็นไฟล์ในดิสก์ เป็นตารางในฐานข้อมูล เป็นเอกสารแบบ XML ที่มาจากเว็บ หรือบ่อยครั้งที่ในงานๆ เดียวต้องพาดพิงแหล่งข้อมูลทุกแบบที่ว่ามานี้ผสมกัน กล่าวโดยถึงที่สุดแล้วไม่ว่าจะพัฒนาซอฟต์แวร์โครงการไหนมักหนีไม่พ้นจะต้องข้องเกี่ยวกับการจัดการข้อมูลในรูปแบบใดรูปแบบหนึ่งเสมอ เมื่อท่านพัฒนาซอฟต์แวร์ท่านย่อมคาดหวังว่าสภาพแวดล้อมจะเอื้ออำนวยให้ท่านจัดการข้อมูลได้ง่าย คือมีเครื่องมือ หรือมีตัวช่วย หรือมีไลบรารี ที่จะทำให้ท่านเข้าถึงแหล่งข้อมูลได้ง่าย ไม่ต้องพัฒนาสิ่งพื้นฐานเอาเองจากศูนย์ทั้งหมด หากท่านพัฒนาซอฟต์แวร์บนดอตเน็ตเฟรมเวิร์ค (Microsoft .NET Framework ย่อ NETFX) ท่านย่อมสบายใจได้ เพราะ NETFX จัดเตรียมกลไกที่เกี่ยวข้องกับการจัดการข้อมูลมาให้อย่างอุดมตั้งแต่เวอร์ชันแรก และยิ่งไปกว่านั้นในเวอร์ชัน 3.5 NETFX ได้จัดเตรียม LINQ ซึ่งช่วยผสานการจัดการข้อมูลเข้ากับภาษา C# ได้ใกล้ชิดขึ้นจนเป็นเนื้อเดียวกัน ก่อนที่จะมุ่งเข้าสู่เนื้อหาที่เป็นรายละเอียดต่างๆ เกี่ยวกับ LINQ ในบทนี้ท่านจะได้เห็นภาพมุมกว้างโดยทั่วๆ ไปของ LINQ เสียก่อน เพื่อให้รู้ว่าอะไรอยู่ที่ใด ซึ่งจะช่วยให้ท่านมองเห็นความสัมพันธ์ระหว่างส่วนต่างๆ ได้ชัดขึ้นเมื่อท่านเรียนถึงเนื้อหาส่วนรายละเอียด แนะนำ LINQ เบื้องต้น โชคดีที่ภาษา 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 บริษัทไมโครซอฟต์รู้ว่าแนวทางของคอดด์นั้นดีเยี่ยมและผู้คนจะไม่เปลี่ยนใจไปจาก 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
มหาเอกะทฤษฏีขณะที่สตีเฟน ฮอว์กินส์ กำลังหาทางรวมทฤษฏีทั้งหมดเข้าด้วยกันให้เป็นทฤษฏีเดียวที่อธิบายได้ทุกอย่างในเอกภพหรือ มหาเอกะทฤษฏี (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 กรุณาติดตามตอนต่อไป |