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

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

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

   [ตอน2]

 

ข้อดีของ LINQ
ก่อนหน้าที่จะมี LINQ การพัฒนาซอฟต์แวร์ที่เกี่ยวข้องกับแหล่งข้อมูลคละแบบ ท่านจำเป็นต้องใช้ API (Application Programming Interface ตัวเชื่อมต่อกับโปรแกรมประยุกต์) ที่แตกต่างกันหลายแบบ แต่ละแบบมีเทคโนโลยีและวิธีใช้งานเป็นของตัวเอง ยกตัวอย่างเช่นเมื่อท่านติดต่อกับ SQL2008 ท่านต้องใช้ ADO.NET เมื่อจะติดต่อกับแฟ้มข้อมูล XML ท่านต้องใช้ API ที่อยู่ภายในเนมสเปส System.Xml สภาพการเช่นนี้สร้างความปวดเศียรเวียนเกล้าให้แก่กรรมกรซอฟต์แวร์กันทั่วหน้า เพราะวิธีเขียนโค้ดติดต่อกับข้อมูลมีโมเดลหลายแบบ ขาดความคงเส้นคงวา ดีใจได้! เพราะต่อไปนี้จะไม่เป็นเช่นนั้นแล้ว LINQ จะช่วยให้ท่านทำงานกับแหล่งข้อมูลทุกชนิดได้ด้วยวิธีที่เหมือนๆ กันหมด

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

ข้อดีอีกอย่างหนึ่งของ LINQ คือนอกจากท่านจะไม่ต้องห่วงว่าคิวรีจะผิดไวยากรณ์ เพราะตัวแปลภาษาจะตรวจสอบ และแจ้งความผิดพลาดให้อย่างที่เรียนไปแล้ว ส่วนอินเทลลิเซนส์ (IntelliSense คุณสมบัติเพื่อตรวจสอบความถูกต้องและเสนอแนะคำที่เหมาะขณะป้อนพิมพ์โค้ดของ VS2008) ยังสามารถทำงานกับ LINQ ได้อย่างก้าวหน้า ช่วยให้การป้อนพิมพ์โค้ดทำได้อย่างสนุก

เรื่องสำคัญที่ไม่ควรมองข้ามอีกประการหนึ่งคือ LINQ ไม่ได้ส่งผลกระทบต่อการทำงานกับข้อมูลเท่านั้น การผสาน LINQ เข้ากับ C# ยังทำให้ภาษา C# เปลี่ยนแปลงไปอย่างสู่รูปโฉมใหม่อีกด้วย วิธีเขียนโค้ดของท่านจะไม่เหมือนเดิมอีกต่อไปแล้ว เพราะในหนังสือเล่มนี้ท่านจะได้เรียนรู้วิธีใช้ประโยชน์จากความเปลี่ยนแปลงที่เกิดขึ้นอย่างกว้างขวางในภาษา C# ที่จะช่วยให้โค้ดของท่านสั้นกระชับแต่จะทรงพลังกว่าเดิม

ภาพ 1-6: ส่วนอินเทลลิเซนส์ (IntelliSense คุณสมบัติเพื่อตรวจสอบความถูกต้องและเสนอแนะคำที่เหมาะขณะป้อนพิมพ์โค้ดของ VS2008) ยังสามารถทำงานกับ LINQ ได้อย่างก้าวหน้า

ชุดเครื่องมือ LINQ
LINQ เหมือนเหรียญที่มีสองด้าน ในด้านหนึ่งมันเป็นชุดเครื่องมือเพื่อใช้ทำงานกับข้อมูล และในอีกด้านหนึ่งมันมีภาวะเป็นส่วนที่เพิ่มขยายความสามารถของภาษา C# ในหัวข้อนี้ผู้เขียนจะพูดถึง LINQ ในแง่ที่เป็นชุดเครื่องมือ ท่านอาจมองว่า LINQ เป็นกล่องเครื่องมือที่มีเครื่องมือมาให้หลายอย่างดังนี้

  • LINQ to Object: เป็นเครื่องมือที่ช่วยให้ท่านทำคิวรีกับข้อมูลที่อยู่ภายในดาต้าคอลเลคชันภายในหน่วยความจำ
  • LINQ to DataSet: เป็นเครื่องมือที่ช่วยให้ท่านทำคิวรีกับข้อมูลที่อยู่ภายในดาต้าเซต
  • LINQ to SQL: เป็นเครื่องมือที่ช่วยให้ท่านทำคิวรีกับข้อมูลที่อยู่ภายในฐานข้อมูล
  • LINQ to Entity: เป็นเครื่องมือที่ช่วยให้ท่านทำคิวรีกับข้อมูลที่อยู่ภายในออพเจ็กต์แบบ ADO.NET เอ็นทิตีเฟรมเวิร์ค
  • LINQ to XML: เป็นเครื่องมือที่ช่วยให้ท่านทำคิวรีกับข้อมูลที่อยู่ภายในแฟ้มข้อมูล XML

ในหนังสือเล่มนี้ท่านจะได้เรียนเครื่องมือที่ LINQ มีมาให้ทั้งห้าแบบนี้โดยละเอียด เครื่องมือห้าแบบนี้บางทีเรียกว่าตัวให้บริการหรือโพรไวเดอร์ (LINQ Provider ย่อ LP) ลองพิจารณาภาพ 1-7 จะเห็นว่าส่วนบนสุดคือภาษาที่ใช้งานกับ LINQ ได้ (ขณะนี้มีเพียงสองภาษาคือ C# 3.0 และ VB 9.0) ระดับถัดลงไปจากภาษาคือส่วนเพิ่มขยายหรือเปลี่ยนแปลงภาษาเพื่อให้ใช้งาน LINQ ได้ ประกอบด้วยสิ่งหลักสามสิ่งคือ ตัวดำเนินการคิวรีมาตรฐาน (Standard Query Operators ย่อ SQO) นิพจน์คิวรี (Query Expression ย่อ QE) และนิพจน์ต้นไม้ (Expression Tree ย่อ ET)

ถัดจากส่วนเพิ่มขยายหรือเปลี่ยนแปลงภาษาเพื่อให้ใช้งาน LINQ ได้คือ LP ประกอบด้วยตัวให้บริการห้าตัวคือ LINQ to Object, LINQ to XML, LINQ to SQL, LINQ to DataSet และ LINQ to Entities ในอนาคตทีมงานผู้สร้าง LINQ อาจเพิ่ม LP แบบใหม่ๆ ขึ้นอีกได้ กรอบล่างสุดคือแหล่งข้อมูลที่ใช้ทำคิวรี (Data Source ย่อ DS) โดย DS แต่ละแบบจะสัมพันธ์กับ LP แต่ละตัว

โปรดทราบว่าส่วน LP ไม่ใช่โปรแกรมที่แยกต่างหากหรือปลั๊กอิน แต่เป็น นวัตกรรมที่ถูกผนวกไว้กับภาษาเขียน C# 3.0เลย ที่เป็นไปได้เช่นนั้นเพราะ NETFX และภาษา C# ถูกดัดแปลงต่อเติมเพื่อให้รองรับ LINQ ได้ดังจะอธิบายรายละเอียดในหัวข้อถัดไป

เนื่องจาก DS แบบ RDBMS, DataSet และ ADO.NET Entity Framework ล้วนสัมพันธ์กับฐานข้อมูลดังนั้นเราจึงอาจจัด LP แบบ LINQ to SQL, LINQ to DataSet และ LINQ to Entities ไว้เป็นกลุ่มเดียวกันได้อย่างที่เห็นในภาพ 1-8

ภาพ 1-7: สถาปัตยกรรม LINQ ที่ประกอบด้วยส่วนหลักสี่ส่วนคือภาษาโปรแกรม ส่วนเพิ่มขยายหรือเปลี่ยนแปลงภาษาเพื่อให้ใช้งาน LINQ ได้ ส่วนตัวให้บริการ LINQ และแหล่งข้อมูล

ภาพ 1-8: เราอาจจัด LP แบบ LINQ to SQL, LINQ to DataSet และ LINQ to Entities ไว้เป็นกลุ่มเดียวกันได้

ความเปลี่ยนแปลงในภาษา C#
การจะทำให้ภาษา C# ใช้งาน LINQ ได้ ฮาเยสเบิร์ก จำเป็นต้องเสริมเพิ่มสิ่งจำเป็นให้แก่ NETFX และภาษา C# การเพิ่มที่ว่านี้ไม่ใช่เป็นแค่เพียง “วากยสัมพันธ์แช่อิ่ม” (Syntactic sugar หมายถึงวากยสัมพันธ์ที่ไม่ได้เพิ่มความสามารถให้ภาษา แต่มีไว้เพื่อให้เขียนโค้ดได้สะดวกหรือสง่างามขึ้น) เพื่อให้ท่านคิวรีฐานข้อมูลในภาษา C# ได้สะดวกขึ้นเท่านั้น แต่เป็นการเพิ่มเติมที่ทำให้ท่านสามารถเขียน “โปรแกรมเชิงเจตจำนง” (Declarative Programming ย่อ DP) ได้

สาเหตุที่ต้องยุ่งเกี่ยวกับ DP เพราะภาษาเพื่อการคิวรีข้อมูลในฐานข้อมูลสัมพันธ์ที่นักเขียนโค้ดคุ้นเคยที่สุดคือภาษา SQL เป็นภาษาแบบ DP ซึ่งเน้นการระบุว่าต้องการผลลัพธ์อย่างไร มีหลักการคิดแตกต่างจากภาษา C# ที่เป็นภาษาเชิงกำหนด (Imperative Programming ย่อ IP) ซึ่งเน้นการระบุว่าต้องการให้ดำเนินการอย่างไร

ในชั้นแรกส่วน DP ที่ถูกเพิ่มเข้าใน C# 3.0 มีเจตนาให้ใช้คิวรีข้อมูลเท่านั้น แต่ภายหลังแนวคิดนี้คลี่คลายออกครอบคลุมส่วนที่ไม่ใช่คิวรีด้วย ดังนั้นใน C# 3.0 นอกจากท่านจะสามารถเขียนโปรแกรมตามลัทธิ IP อย่างที่เคยปฏิบัติมาแต่เดิมแล้วท่านยังอาจเขียนโปรแกรมตามลัทธิ DP ได้อีกด้วย

ต่อไปลองมาดูตัวอย่างสิ่งที่เพิ่มขึ้นในภาษา C# เพื่อให้คิวรีข้อมูลได้โดยใช้ LINQ สมมุติว่าท่านได้รับโจทย์ดังนี้ “จงคิวรีข้อมูลในตาราง Products ในฐานข้อมูล AdventureWork2008 เฉพาะแถวที่รหัสสินค้ามากกว่า 2 และชื่อสินค้านำหน้าด้วย A จากนั้นนำผลลัพธ์ที่ได้ไปใส่ในโครงสร้างแบบ XML ในหน่วยความจำ” โจทย์แบบนี้หากไม่ใช้ LINQ ท่านจะต้องเขียนโค้ดโดยใช้เทคโนโลยีสองอย่างผสมกัน คือใช้ ADO.NET เพื่อคิวรีฐานข้อมูล และใช้เนมสเปส System.Xml ของ NETFX เพื่อจัดการ XML แต่ถ้าใช้ LINQ โค้ดจะเป็นอย่างที่เห็นในภาพ 1-9

โค้ดในภาพ 1-9 บรรทัดที่ 13 ถึง 20 ทำหน้าที่คิวรีข้อมูลในตาราง Products ในฐานข้อมูล AdventureWork2008 เฉพาะแถวที่รหัสสินค้ามากกว่า 2 และชื่อสินค้านำหน้าด้วย A บรรทัดที่ 21 ถึง 29 ทำหน้าที่นำผลลัพธ์ไปใส่ในโครงสร้างแบบ XML ในหน่วยความจำ สิ่งที่เพิ่มขึ้นในภาษา C# 3.0 คือส่วน QE ในบรรทัดที่ 16 ถึง 20 จะเห็นว่ามีคำสั่ง from, where, orderby และ select หากนำโค้ดนี้คอมไพล์ใน C# 2.0 ท่านย่อมจะได้รับข้อความแจ้งความผิดพลาดเป็นจำนวนมาก

ท่านจะได้เรียนรายละเอียดเกี่ยวกับ QE พร้อมเบื้องหน้าและเบื้องหลังอย่างพิสดารในบทต่อๆ ไป แต่ในหัวข้อนี้ผู้เขียนเพียงอยากจะให้ท่านตั้งข้อสังเกตว่าอันที่จริงแล้ว LINQ ไม่ใช่ภาษาใหม่ และ QE ก็ไม่ใช่ภาษาใหม่ด้วยเช่นกัน คิวรีที่ท่านเห็นในบรรทัดที่ 16 ถึง 20 แท้จริงแล้วเป็นภาษา C# โปรดตระหนักว่าบัดนี้ท่านสามารถคิวรีข้อมูลจากแหล่งข้อมูลอะไรก็ได้จากบรรทัดคำสั่งภาษา C# โดยตรง สภาพการเช่นนี้เป็นสิ่งที่กรรมกรซอฟต์แวร์ทุกผู้ทุกนามล้วนใฝ่ฝันมานานมิใช่หรือ

ภาพ 1-9: โค้ดภาษา C# ใช้งาน LINQ เพื่อทำงานตามโจทย์ว่าจงคิวรีข้อมูลในตาราง Products ในฐานข้อมูล AdventureWork2008 เฉพาะแถวที่รหัสสินค้ามากกว่า 2 และชื่อสินค้านำหน้าด้วย A จากนั้นนำผลลัพธ์ที่ได้ไปใส่ในโครงสร้างแบบ XML ในหน่วยความจำ

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

ปัญหาของ ADO.NET ก่อนหน้ามี LINQ ท่านจะใช้ ADO.NET เพื่อติดต่อกับฐานข้อมูล แท้จริง ADO.NET เป็นเพียงไลบรารีพื้นฐานของดอตเน็ต (.NET Framework Class Library ย่อ FCL) คือเป็นชุด API อันประกอบด้วยคลาสต่างๆ เช่น SqlConnection, SqlCommand, SqlReader, DataSet และ DataTable ฯลฯ ปัญหาของการใช้คลาสเหล่านี้คือท่านจะต้องอ้างถึงตาราง คอลัมน์ และแถวข้อมูลโดยตรง และปรกติในฐานข้อมูลจะมีตารางและคอลัมน์จำนวนมาก การดึงข้อมูลออกจากตารางมาใส่ในหน่วยความจำและการใส่ข้อมูลที่แก้ไขแล้วกลับคืนเข้าไปในตาราง ท่านต้องเขียนรายการคอลัมน์ยืดยาว มีการประเมินว่าทีมนักพัฒนาเสียเวลาไปกับกิจกรรมเหล่านี้คิดเป็นร้อยละ 30 ถึง 40 ของเวลาทั้งโครงการ

ปัญหาของการใช้ ADO.NET ไม่ได้หยุดอยู่เพียงเรื่องประสิทธิภาพในการพัฒนา แต่ยังลามไปถึงคุณภาพของงานด้วย บ่อยครั้งที่นักเขียนโค้ดเผอเรอกำหนดชนิดข้อมูลผิดต้องไล่หาบักอย่างยากลำบาก บางครั้งอาจไม่พบความผิดปรกตินี้จนกว่าจะใช้งานจริงไปสักพัก

 ภาพ 1-10 แสดงโค้ดที่ใช้ ADO.NET ติดต่อฐานข้อมูล AdventureWork2008 เพื่อคิวรีตาราง Products ไล่เรียงข้อจำกัดต่างๆ ได้ดังนี้

•    บรรทัดที่ 11 ถึง 13 โค้ดกำหนดการเชื่อมต่ออยู่ในสภาพสตริง ตัวแปลภาษาจึงไม่รับรู้หากกำหนดค่าผิด
•    บรรทัดที่ 17 และ 18 เป็นคิวรีที่อยู่ในสภาพสตริง ตัวแปลภาษาจึงไม่รับรู้หากเขียนคิวรีผิด
•    บรรทัดที่ 25 และ 26 ผู้เขียนโค้ดไม่รู้ว่าข้อมูลที่รับมาเป็นไทป์อะไรเพราะส่วนอินเทลลิเซนส์ไม่สามารถแสดงคำแนะนำใดๆ ได้
•    หากเปลี่ยนดาต้าเบสเซอฟเวอร์ (เช่นเปลี่ยนจากเซอฟเวอร์ที่ใช้ในการทดสอบไปเป็นเซอฟเวอร์ที่ใช้งานจริง) โค้ดนี้จะเออเรอร์ทันที นอกเสียจากว่าจะแก้ไขส่วนกำหนดการเชื่อมต่อเสียก่อน

 ภาพ 1-11 แสดงโค้ดที่ใช้ LINQ ติดต่อฐานข้อมูล AdventureWork2008 เพื่อคิวรีตาราง Products ไล่เรียงการแก้ปัญหาต่างๆ ได้ดังนี้

•    บรรทัดที่ 40-14 การกำหนดการเชื่อมต่ออยู่ในสภาพออพเจ็กต์ที่ตัวแปรภาษารับรู้
•    บรรทัดที่ 43-44 คิวรีทำในภาษา C# โดยตรง ตัวแปรภาษาตรวจสอบวากยสัมพันธ์ได้
•    บรรทัด 49-30 เนื่องจาก r เป็นออพเจ็กต์ ส่วน ProductID และ Name มีภาวะเป็นพร็อพเพอร์ตีสมาชิกของ r  อินเทลลิเซนส์จึงสามารถแสดงคำแนะนำได้
•    หากเปลี่ยนดาต้าเบสเซอฟเวอร์ (เช่นเปลี่ยนจากเซอฟเวอร์ที่ใช้ในการทดสอบไปเป็นเซอฟเวอร์ที่ใช้งานจริง) ท่านไม่ต้องแก้ไขอะไรในโค้ดนี้เลย เพียงแต่เปลี่ยน O/RM ใหม่

 

ภาพ 1-10 โค้ดที่ใช้ ADO.NET ติดต่อฐานข้อมูล AdventureWork2008 เพื่อคิวรีตาราง Products

ภาพ 1-11 โค้ดที่ใช้ LINQ ติดต่อฐานข้อมูล AdventureWork2008 เพื่อคิวรีตาราง Products

 

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

Advertisements

ทำความรู้จัก 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

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