"อย่าเลื่อนออกไปจนกว่าจะถึงรันไทม์สิ่งที่สามารถทำได้ในเวลาคอมไพล์"
David Gries โครงสร้างคอมไพเลอร์สำหรับคอมพิวเตอร์ดิจิทัล
บทนำ
ในฐานะโปรแกรมเมอร์ เมื่อเราเรียนรู้เทคโนโลยีใหม่ บางครั้งตัวอย่างอาจเป็นศัตรูตัวฉกาจที่สุดของเรา Guidelines มักได้รับการออกแบบให้เรียบง่ายและเข้าใจง่าย แต่ในขณะเดียวกัน Guidelines ก็สามารถนำไปสู่การเพิ่มจำนวนการเขียนโค้ดที่เกียจคร้าน ไม่มีประสิทธิภาพ และแม้กระทั่งเป็นอันตรายได้ สถานการณ์ที่พบบ่อยที่สุดเช่นนี้อยู่ในกระบวนทัศน์ ADO.NET ในบทความนี้ เราจะมาดูความหมายของการพิมพ์อ็อบเจ็กต์ที่เจาะจงในฐานข้อมูล ซึ่งช่วยให้คุณดำเนินการดังกล่าวในโปรแกรมของคุณได้ แม้ว่าจะไม่มีตัวอย่างก็ตาม
โดยเจาะจงมากขึ้นอีกเล็กน้อย เราจะดูว่าชุดข้อมูลที่พิมพ์ออกมานั้นถูกสร้างและใช้งานอย่างไรใน Visual Studio 2005 ตามที่อธิบายในบทความนี้ ชุดข้อมูลที่พิมพ์อย่างเข้มงวดมีข้อดีหลายประการเหนือเทคนิคการเข้าถึงข้อมูลที่พิมพ์อย่างไม่รัดกุมอื่นๆ เราจะเห็นที่นี่ด้วยว่าการสร้างและการใช้ชุดข้อมูลที่พิมพ์อย่างยิ่งนั้นจะไม่ง่ายไปกว่านี้ด้วย Visual Studio 2005 หากคุณต้องการเรียนรู้เพิ่มเติม โปรดอ่านต่อ
พื้นฐานและประโยชน์ของวัตถุที่พิมพ์ชัดเจน
เพื่อทำความเข้าใจว่าการพิมพ์ที่ดีหมายถึงอะไร คุณต้องคิดถึงการออกเดทก่อน ถ้าคุณเป็นโสด คุณจะพิจารณาออกเดทกับคนแบบไหน เพราะเหตุใด คุณอาจมีเกณฑ์เฉพาะ (เช่น มีสุขภาพแข็งแรงและมีเสน่ห์) หรือเกณฑ์อาจเรียบง่ายหรือไม่ชัดเจน ไม่ว่าเงื่อนไขของคุณจะเป็นเช่นไร เมื่อคุณตัดสินใจว่าจะใช้เวลาร่วมกับใครมากขึ้น คุณจะใช้มาตรฐานของคุณเองเสมอเพื่อชั่งน้ำหนักและพิจารณาประเภทเหล่านี้ หากคุณฉลาด คุณจะคิดมากเพื่อปกป้องตัวเองจากบาดแผลทางอารมณ์ คุณอาจพบว่าการอยู่กับคนที่ติดแอลกอฮอล์นั้นไม่มั่นคงเว้นแต่ว่าทั้งสองจะมีความสัมพันธ์ที่จริงจัง อย่างไรก็ตาม การทำให้คนเราเปลี่ยนแปลงเป็นเรื่องที่เจ็บปวดและยากมาก ดังนั้นภูมิปัญญาของคุณจะสั่งให้คุณหยุดความสัมพันธ์ก่อนที่จะเริ่มต้นเสียอีก การเพิ่มเงื่อนไขห้ามดื่มเข้าไปในเกณฑ์การออกเดทของคุณจะช่วยปกป้องคุณจากความเสียใจในอนาคต และช่วยให้คุณมีเวลาและพลังงานไปกับผู้สมัครที่ดีกว่า
คุณอาจแปลกใจว่าเหตุผลนี้เกี่ยวข้องกับการเขียนโปรแกรมอย่างไร ไม่เป็นไร มากับฉันนะนักอ่านที่น่ารัก! ออบเจ็กต์การเข้าถึงข้อมูล ADO.NET ได้รับการออกแบบให้มีความยืดหยุ่นอย่างมาก เมื่อคุณอ่านข้อมูลจากฐานข้อมูล คุณอาจทำงานกับออบเจ็กต์ทั่วไปหลายประเภทที่อนุญาตโดยเฟรมเวิร์ก .NET ปกติ เว้นแต่ว่าคุณจะพบปัญหาพิเศษ เมื่อใช้ทฤษฎีการออกเดทของเรา คุณสามารถคิดว่าข้อมูลที่เกี่ยวข้องของคุณเป็นวัตถุสากลได้ “ตราบใดที่เดทของฉันไม่เป็นปัญหามากเกินไป” คุณช่วยอธิบายให้ชัดเจนกว่านี้หน่อยได้ไหม? ไม่มีขีดจำกัดแม้ว่าจะเป็นมนุษย์หรือสิ่งมีชีวิตอื่นๆ ก็ตาม! ในฐานะเพื่อนของคุณ ฉันขอร้องคุณว่า "มีมาตรฐานมากขึ้น! ทำให้รายการของคุณเล็กลง!"
เช่นเดียวกับการละเลยคนที่คุณเดทด้วยอาจทำให้เกิดปัญหาความสัมพันธ์ในอนาคต การปล่อยให้อ็อบเจ็กต์ของคุณไม่ถูกตรวจสอบในโค้ดของคุณก็อาจทำให้เกิดข้อผิดพลาดได้เช่นกัน นอกจากนี้ หากคุณปล่อยให้อ็อบเจ็กต์เก่าเดินไปรอบๆ ในรูทีนย่อยของคุณ คุณอาจไม่สังเกตเห็นว่าปัญหานี้จะเกิดขึ้นจนกว่าโปรแกรมจะทำงาน ในการใช้ทฤษฎีการออกเดทของเรา การตรวจจับข้อผิดพลาดในขณะรันไทม์ก็เหมือนกับการที่คู่เดทของคุณทะเลาะกันอย่างเจ็บปวดและอึดอัดกลางร้านอาหารอิตาเลียนสุดเก๋ ใช่ คุณเห็นไหมว่าถ้าคุณวางแผนล่วงหน้า คุณจะไม่ถูกคนมารับประทานอาหารกลุ่มใหญ่มองมาที่คุณ และมันคงจะไม่ใช่เรื่องน่าอาย เพียงใช้มาตรฐานที่เข้มงวดยิ่งขึ้นกับโค้ดของคุณ คุณสามารถตรวจพบข้อผิดพลาดก่อนที่โปรแกรมของคุณจะเริ่มคอมไพล์ ตัวอย่างเช่น ตัวอย่างโค้ดต่อไปนี้:
string FirstName = myrow.("FirstName").ToString();
DataRow ในตัวอย่างนี้ไม่ได้พิมพ์ และด้วยเหตุนี้ คุณต้องใช้ชื่อคอลัมน์เป็นสตริงเพื่อรับค่าที่คุณต้องการ (หรือคุณสามารถเลือกใช้ดัชนีของคอลัมน์ในคอลเลกชันคอลัมน์ของระเบียนได้) โชคดีที่มีคอลัมน์นั้นอยู่ ชนิดข้อมูลของคอลัมน์ DataRow เป็นวัตถุ เราถือว่าชนิดข้อมูลภายใต้คอลัมน์ FirstName เป็นสตริง และเราต้องแปลงเป็นสตริงอย่างชัดเจนก่อนที่จะใช้งาน หากชื่อของคอลัมน์นี้เปลี่ยนแปลง (เช่น กลายเป็น PersonFirstName) คอมไพเลอร์จะไม่สามารถแจ้งให้คุณทราบได้ หดหู่? แต่คุณไม่จำเป็นต้อง หากโค้ดของคุณมีลักษณะดังต่อไปนี้ ชีวิตของคุณก็จะง่ายขึ้น และโค้ดของคุณก็จะน่าเชื่อถือมากขึ้น
string FirstName = PersonRow.FirstName;
ในตัวอย่างนี้ เราใช้แถวที่พิมพ์อย่างยิ่ง และเรารู้ว่าคุณสมบัติ FirstName เป็นประเภทสตริง ไม่มีชื่อคอลัมน์ที่ยุ่งเหยิง ไม่มีการแปลงประเภทที่ยุ่งเหยิง คอมไพลเลอร์ได้ทำการตรวจสอบประเภทให้เราแล้ว และเราสามารถทำงานอื่นได้อย่างปลอดภัยโดยไม่ต้องกังวลว่าเราพิมพ์ชื่อคอลัมน์ถูกต้องหรือไม่
อย่างอื่นก็เหมือนกัน ดังนั้นคุณจะไม่ลังเลเลยที่จะใช้สิ่งนี้แทนประเภททั่วไป แต่เดี๋ยวก่อน วัตถุที่พิมพ์อย่างรุนแรงมาจากไหน? ฉันหวังว่าฉันจะบอกคุณได้ว่าวัตถุเหล่านี้ถูกสร้างขึ้นโดยอัตโนมัติ แต่เช่นเดียวกับความสัมพันธ์ที่ดีต้องใช้เวลาและความพยายาม การทำให้วัตถุของคุณพิมพ์ชัดเจนต้องใช้ความพยายามเป็นพิเศษ แต่การใช้เวลาเพิ่มเติมที่นี่คุ้มค่าอย่างแน่นอน และช่วยประหยัดเวลาในการ "จับแมลง" ได้มากขึ้นในอนาคต
มีหลายวิธีในการพิมพ์ที่แข็งแกร่ง และเราจะใช้เวลาส่วนที่เหลือของบทความนี้เพื่ออธิบายวิธีสร้างชุดข้อมูลที่มีการพิมพ์สูงใน Visual Studio 2005 เราจะเปรียบเทียบข้อดีและข้อเสียของแนวทางนี้กับวิธีอื่นด้วย
การสร้างชุดข้อมูลที่พิมพ์อย่างเข้มงวดใน Visual Studio 2005
ชุดข้อมูลที่พิมพ์อย่างเข้มงวดนั้น แท้จริงแล้วเป็นเพียงคอลัมน์และตารางที่กำหนดไว้ล่วงหน้าของชุดข้อมูลธรรมดา ดังนั้นคอมไพลเลอร์จึงรู้อยู่แล้วว่าชุดข้อมูลเหล่านั้นประกอบด้วยอะไร แทนที่จะเป็นกระดาษห่อหลวมที่เหมาะกับคุณเหมือนถุงมือเบสบอล ชุดข้อมูลที่พิมพ์อย่างยิ่งจะพอดีกับถุงมือ Visual Studio เวอร์ชันต่อเนื่องกันแต่ละเวอร์ชันช่วยให้จัดการชุดข้อมูลที่พิมพ์อย่างเข้มงวดได้ง่ายขึ้น ในตัวอย่างต่อไปนี้ เราจะใช้ฐานข้อมูล AdventureWorks ของ SQL Server 2005 เพียงทำตามขั้นตอนเหล่านี้:
1. เปิด Visual Studio และสร้างเว็บไซต์ ASP.NET ใหม่
2. ในหน้าต่าง Solution Explorer คลิกขวาเพื่อเพิ่มรายการใหม่และเลือก DataSet ตั้งชื่อมันว่า AdventureWorks.xsd (ดูภาพหน้าจอ) Visual Studio จะแนะนำให้คุณใส่ไฟล์ DataSet ลงในไฟล์ App_Code และคุณเพียงแค่ต้องคลิก Agree
3. หลังจากเปิด AdventureWorks.xsd ในโหมดออกแบบ ตัวช่วยสร้างการกำหนดค่า TableAdapter จะทำงาน ณ จุดนี้ คลิกยกเลิก แล้วเราจะลากตารางที่ต้องการจาก Server Explorer
4. เรียกดูเพื่อค้นหาฐานข้อมูล AdventureWorks ในแถบเครื่องมือ Server Explorer (หากคุณไม่ได้ติดตั้งฐานข้อมูล AdventureWorks คุณสามารถไปที่หน้าดาวน์โหลดตัวอย่าง SQL Server 2005 และฐานข้อมูลตัวอย่างของ Microsoft เพื่อดาวน์โหลดและตัวอย่าง SQL Server 2005 อื่นๆ)
5. ลากตาราง SalesOrderHeader และตาราง SalesOrderDetail ลงในหน้าต่างการออกแบบชุดข้อมูล หน้าต่างควรมีลักษณะเหมือนในภาพหน้าจอ เราเห็นอะไร? เมื่อใดก็ตามที่เราเพิ่มตาราง Visual Studio จะสร้าง DataTable ที่พิมพ์อย่างยิ่ง (ซึ่งมีชื่อเดียวกับตารางดั้งเดิม) และ TableAdapter DataTable นี้ได้กำหนดแต่ละคอลัมน์ให้เราแล้ว TableAdapter คือสิ่งที่เราใช้ในการเติมตาราง โดยค่าเริ่มต้น จะมีเมธอด Fill() เพื่อรับข้อมูลแต่ละแถวจากตารางต้นฉบับ
ตามที่เป็นอยู่ ชุดข้อมูลที่พิมพ์อย่างยิ่งนี้จะส่งคืนระเบียนทั้งหมดจากทั้งสองตาราง แต่ฐานข้อมูล AdventureWorks มีข้อมูลการสั่งซื้อจำนวนมาก ดังนั้นทำไมไม่สร้างแบบสอบถามที่ชัดเจนกว่านี้ล่ะ เราสามารถเพิ่มวิธีการให้กับวัตถุ TableAdapter เพื่อรับชุดระเบียนย่อยเฉพาะ คลิกขวาที่ SalesORderHeaderTableAdapter และเลือกเพิ่ม|แบบสอบถาม เลือก "ใช้คำสั่ง SQL" แล้วคลิกถัดไป จากนั้นเลือก "เลือกที่ส่งคืนแถว" แล้วคลิกถัดไป เมื่อเร็วๆ นี้ ให้ป้อนคำค้นหาต่อไปนี้ลงในหน้าต่าง (หรือคุณสามารถใช้ Query Builder เพื่อดำเนินการได้):
เลือก
SalesOrderID, หมายเลขการแก้ไข, OrderDate, DueDate, ShipDate,
สถานะ, OnlineOrderFlag, SalesOrderNumber, PurchaseOrderNumber,
หมายเลขบัญชี, รหัสลูกค้า, รหัสผู้ติดต่อ, รหัสพนักงานขาย, รหัสอาณาเขต,
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID,
CreditCardApprovalCode, CurrencyRateID, SubTotal, TaxAmt, ค่าขนส่ง,
TotalDue, ความคิดเห็น, rowguid, ModifiedDate
จาก Sales.SalesOrderHeader
โดยที่ (วันที่สั่งซื้อ > @วันที่สั่งซื้อ)
แบบสอบถาม SQL นี้เป็นแบบสอบถาม SELECT แบบธรรมดา โดยใช้พารามิเตอร์ @OrderDate เพื่อกรองผลลัพธ์ สิ่งนี้จะช่วยเราจากการส่งคืนบันทึกทั้งหมดในฐานข้อมูล เลือกช่องทำเครื่องหมาย "Fill a DataTable" และ "Return a DataTable" แล้วคลิก Finish หลังจากเพิ่มคำสั่ง SELECT นี้แล้ว ตัวออกแบบของคุณควรมีลักษณะเหมือนภาพหน้าจอ พร้อมด้วยแบบสอบถามเพิ่มเติมภายใต้ SalesOrderHeaderTableAdapter
หลังจากสร้างชุดข้อมูลที่พิมพ์อย่างหนักแล้ว เราสามารถแสดงข้อมูลในหน้า ASP.NET ด้วยโค้ดเพียงไม่กี่บรรทัดได้อย่างง่ายดาย สร้างเพจ ASP.NET ใหม่บนเว็บไซต์และสลับไปที่โหมดการออกแบบ ลากตัวควบคุม GridView ไปไว้บนนั้น และปล่อยให้ ID เป็น GirdView1 จากนั้นไปที่หน้าซอร์สโค้ดและแนะนำเนมสเปซ AdventureWorksTableAdapters เหนือไฟล์ (ไวยากรณ์ใน c# ใช้ AdventureWorksTableAdapters;) สุดท้าย เพิ่มโค้ดต่อไปนี้ในเหตุการณ์ Page_Load:
// สร้าง SalesOrderHeaderTableAdapter
SalesOrderHeaderTableAdapter salesAdapter =
new SalesOrderHeaderTableAdapter();
// รับคำสั่งซื้อที่เกิดขึ้นหลังวันที่ 1 กรกฎาคม 2004
คำสั่งซื้อ AdventureWorks.SalesOrderHeaderDataTable =
salesAdapter.GetDataBy(new DateTime(2004, 7, 1));
// ผูกผลลัพธ์การสั่งซื้อเข้ากับ GridView
this.GridView1.DataSource = คำสั่งซื้อ;
นี้.GridView1.DataBind();
รหัสนั้นง่ายมาก เราสร้างอินสแตนซ์ของ SalesORderHeaderTableAdapter เพื่อเติมตารางข้อมูล สิ่งที่ควรสังเกตที่นี่คือไม่เหมือนกับ DataTable ทั่วไป เราประกาศวัตถุประเภท SalesORderHeaderDataTable เราเรียกเมธอด GetDateBy() และส่งวัตถุ DateTime เพื่อกรอกข้อมูล โปรดทราบด้วยว่าคำสั่งที่ได้รับนั้นถูกพิมพ์อย่างหนักเช่นกัน ดังนั้นเราต้องส่งวัตถุ DateTime แทนที่จะเป็นวัตถุธรรมดา ภาพหน้าจอด้านล่างเป็นผลจากตัวอย่างโค้ดด้านบน
นอกเหนือจากการใช้โค้ดเพื่อผูกชุดผลลัพธ์กับ GridView แล้ว คุณยังสามารถใช้ ObjectDataSource ตั้งค่าคุณสมบัติ TypeName เป็น AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter และตั้งค่า SelectMethod เป็น GetData หรือ GetDataBy
นอกจากไม่ต้องเขียนโค้ดเพื่อเชื่อมต่อกับฐานข้อมูลแล้ว ข้อดีอีกประการหนึ่งของการใช้ชุดข้อมูลที่พิมพ์อย่างเข้มงวดก็คือ ไม่มีสตริงชื่อคอลัมน์ที่ซ่อนอยู่ในโค้ดของเราซึ่งคอมไพเลอร์ไม่สามารถตรวจสอบได้ เราไม่จำเป็นต้องทำการแปลงประเภทใดๆ เช่นกัน หากสคีมาฐานข้อมูลเปลี่ยนแปลง เพียงอัปเดตไฟล์ AdventureWorks.xsd แล้วเราจะพบว่าการเปลี่ยนแปลงที่เกี่ยวข้องทั้งหมดจะเสร็จสมบูรณ์โดยอัตโนมัติ ณ เวลาคอมไพล์
เทคนิคอื่นๆ สำหรับการสร้างแอปพลิเคชันการเข้าถึงข้อมูลแบบ Strongly-Typed
นอกเหนือจากการใช้ชุดข้อมูลที่พิมพ์แบบ Strongly แล้ว ยังมีวิธีอื่นๆ ในการใช้การพิมพ์แบบ Strongly ในโปรแกรมของคุณ คุณสามารถสร้างคลาสแบบกำหนดเองที่มีน้ำหนักเบากว่าชุดข้อมูลและสอดคล้องกับฐานข้อมูลของคุณมากกว่า นอกจากนี้ยังมีนักพัฒนาซอฟต์แวร์บุคคลที่สามบางรายที่ได้พัฒนาเครื่องมือเพื่อทำให้กระบวนการนี้เป็นไปโดยอัตโนมัติ สิ่งหนึ่งที่พิเศษและฉันชอบที่สุดคือ LLBLGen Pro ฉันเคยเขียนหนังสือเกี่ยวกับเรื่องนี้: Rapid C# Windows Development: Visual Studio 2005, SQL Server 2005 และ LLBLGen Pro (คุณสามารถอ่านหนังสือได้ฟรี 1/3 เล่มบนเว็บไซต์ของฉัน) เครื่องมือยอดนิยมอีกอย่างหนึ่งคือ CodeSmith แม้แต่ Microsoft ก็กำลังพัฒนาเครื่องมือเล็กๆ ที่เรียกว่า DLINQ แต่ก็ยังอยู่ระหว่างการทดสอบและคาดว่าจะยังไม่เปิดตัวจนกว่าจะถึงปีหน้าเป็นอย่างน้อย
หากคุณใช้วิธีการชุดข้อมูลที่แข็งแกร่งของ Visual Studio ข้อดีประการหนึ่งที่ปฏิเสธไม่ได้ก็คือคุณไม่จำเป็นต้องซื้อซอฟต์แวร์เพิ่มเติม โซลูชันทั้งหมดนี้มีคุณสมบัติและคุณประโยชน์ที่แตกต่างกัน แต่ประโยชน์หลักคือความน่าเชื่อถือ ข้อผิดพลาดน้อยลง และใช้เวลาแก้ไขข้อบกพร่องน้อยลง นอกจากนี้ยังง่ายกว่าที่จะตรวจสอบผลกระทบของการเปลี่ยนแปลงสคีมาฐานข้อมูลและดำเนินการบำรุงรักษา หวังว่าคุณจะตระหนักถึงประโยชน์ของการพิมพ์ที่ดี ขอให้โชคดีกับการพัฒนา (และการออกเดทด้วย)!
โดย โจเซฟ เสนาเซลเลอร์
เอกสารแนบ
ดาวน์โหลดโค้ดที่ตรวจสอบในบทความนี้
เกี่ยวกับผู้เขียน
Joseph Chancellor เป็นนักพัฒนา C# ในแคลิฟอร์เนียตอนใต้ซึ่งมีส่วนแบ่งทางความสัมพันธ์ที่ยุติธรรม เขายินดีกับคำติชมและข้อเสนอแนะทุกประเภท เยี่ยมชมบล็อกของเขาหรืออ่านหนังสือห้าบทแรกของเขาใน Visual Studio 2005, SQL Server 2005 และ LLBLGen Pro
ที่อยู่เดิม: http://aspnet.4guysfromrolla.com/articles/020806-1.aspx