O/R Mapping: May I introduce Gentle.NET?

เกริ่นนำ

    ในบทความที่ผ่านๆ มา ผมแนะนำให้เห็นพื้นฐานของการทำ O/R Mapping หลังจากที่รอคอยมานาน วันนี้ผมขอแนะนำเครื่องมือช่วยสักตัวหนึ่งที่ชื่อว่า Gentle.Net แต่เดี๋ยวก่อนครับ ไม่ใช่ว่าเรื่องพื้นฐานจบแล้วนะครับ เพียงแค่กลัวว่าจะเบื่อกัน พูดแต่เรื่องทฤษฎี ผมเลยขอตัดตอนไปที่เครื่องมือก่อน จะได้เอาไปทดลองใช้กันได้ แล้วบทต่อๆ ไป ค่อยมาดูพื้นฐานกันต่อ จะได้เอาเครื่องมือไปประยุกต์ได้ทันที

ว่ากันด้วยเรื่องเครื่องมือบน .NET

    การทำ O/R Mapping จะสมบูรณ์ไม่ได้เลยถ้าขาดเครื่องมือ เครื่องมือที่ว่านี้ต้องสามารถบัง SQL ออกจากตัวเราได้ ถ้าเราไม่ได้เขียน SQL แล้วใครจะเขียน ในเมื่อในที่สุดแล้วฐานข้อมูลของเราก็คือ RDBMS ซึ่งยอมคุยกับเราผ่านคำสั่ง SQL เพียงอย่างเดียว คำตอบนั้นผมก็ตอบไปก่อนถามแล้ว ก็เครื่องมือที่ว่านั่นเอง

    ในโลกของ .NET นั้นมีเครื่องมือในการทำ O/R Mapping อยู่หลายตัว ลองเข้าไปดู ที่นี่ ครับ เขารวบรวมเครื่องมือ O/R Mapping ของ .NET ไว้เยอะมาก (แต่เชื่อว่า ยังตกสำรวจอีกมาก) วันนี้วันที่ผมเขียนบทความหน้านี้ ผมนับดูได้ 37 ตัวครับ ไม่น้อยเลยทีเดียว เลือกกันไม่ถูกเลย รักพี่เสียดายน้อย ผมยอมรับเลยนะครับว่า ไม่มีเวลาเพียงพอไปไล่ดูทุกๆ ตัว เลยไม่อาจบอกว่าตัวไหนดีที่สุด ผมใช้วิธีเข้าไปใน USENET อ่านดูความเห็นของโปรแกรมเมอร์ทั้งหลายว่า เขาชอบตัวไหนกันบ้าง ก็พอได้จับได้ตัวเด่นๆ ดังนี้ครับ Gentle.NET, NHibernate, OJB.NET, IBatis.NET, LLBGen Pro, WilsonORMapping  และ NEO แต่ขอบอกก่อนนะครับ ผมไม่ได้เรียงตามลำดับความชอบแต่อย่างได

ทำไมต้อง Gentle.NET

    ผมออกตัวก่อนนะครับว่า ก่อนหน้านี้ประมาณ เดือนหรือสองเดือนนี้ ใน 37 ตัวนี้ผมใช้ไม่เป็นสักตัวเดียว เครื่องมือ O/R Mapping นั้นผมเรียนมาจากทางฝั่ง Java ครับ มีทั้ง Hibernate, OJB, IBatis และ Toplink แต่เพิ่งจะมีโอกาสได้ใช้ O/R Mapping บน .NET ก็งานชิ้นใหม่ที่กำลังทำนั่นเอง ขณะนี้เพียงขั้นเตรียมงาน ยังไม่ได้เริ่มเขียนเลย จึงอาจสรุปได้ว่า ผมไม่มีประสบการณ์ตรงกับ O/R Mapping บน .NET เลยครับ

     แต่นั่นก็ไม่ใช่ปัญหาแต่อย่างใด เพราะศาสตร์ทาง O/R Mapping มันก็มีมาตรฐานอยู่แล้วไม่ว่าใช้เครื่องมืออะไร มันทำให้จับหลักได้โดยไม่ยาก สองเดือนที่ผ่านมา ผมทดลอง NHibernate ซึ่งให้ผลคล้ายกับ Hibernate บน Java มาก จนแทบจะเหมือนกัน และผมเองก็ผ่านร้อนผ่านหนาวกับ Hibernate มามากพอสมควร พอบอกได้ว่ามันเข้าท่ามาก

    แล้วทำไมผมจั่วหัวเป็น Gentle.NET จริงๆ ก็ไม่มีอะไรมากครับ ผมมีสี่เหตุผล

เริ่มกันดีกว่าครับ

    เริ่มกันเลยครับดีกว่าครับ ให้ไป Download Gentle.NET จาก http://sourceforge.net/projects/gopf ขออ้างอิง version หน่อย version ที่ผมได้วันนี้คือ 1.2.3 (ผมเขียนบทความไปด้วยแล้วทำไปด้วย เพิ่ง Download เสร็จครับ) เมื่อ Download เสร็จแล้ว unzip ไว้ที่ใดที่หนึ่ง โดยส่วนตัวแล้ว ผมจะเอา Library .NET เก็บ ลงที่ c:\dotnet  ดังนั้นผมจึง unzip ลงไปที่ c:\dotnet\gentle

    ผมเห็นชื่อ Assembly ของ Gentle.NET แล้วทำให้เพิ่งรู้ว่า มันรองรับ DBMS ดังต่อนี้ Firebird, Jet, MySQL, Oracle, PostgreSQL, SQLite, MSSQL และ Sybase เรียกได้ว่าค่อนข้างครบถ้วนทีเดียว วันนี้ผมเลือก Microsoft Access (Jet) ดีกว่า ด้วยเหตุผลง่ายๆ สองข้อครับ คือมันหาง่าย และ NHibernate (0.8.4) ยังไม่รองรับ Microsoft Access เอาครับ Search ใน Harddisk ดู เชื่อว่าคุณคงหา nwind.mdb พบ เราจะใช้ตัวนี้กันครับ

เตรียม Project

    เข้า Visual Studio .NET สร้าง C# Console Project ครับ (ผมจะลองใช้ VS.NET 2005 beta 2 ดู แต่คุณจะใช้ 2003 ก็ไม่ว่ากัน) จากนั้น Reference Library ของ Gentle.NET จาก Directory Output\Release เอา .dll ดังต่อไปนี้ครับ  Gentle.Common, Gentle.Framework, Gentle.Provider.Jet ทุกตัว, log4net, QuickGraph, QuickGraph.Algorithm

    จากนั้นให้ Add Existing Item เอา nwind.mdb ใส่เข้ามา VS.NET 2005 พอตรวจเจอว่าเป็นฐานข้อมูล มันเรียก Wizard ขึ้นมาเพื่อมันจะไปทำเป็น Strong Name DataSet วันนี้เราอยู่คนละโลกแล้ว เราจะใช้ Gentle.NET ไม่เอา ADO.NET ดังนั้นหน้าจอ Wizard เลยถูก Cancel ไป

    มาถึงจุดนี้ ถ้าใครใช้ VS.NET 2003 จะพบปัญหาครับ ถึงจะ Add เอา nwind.mdb มา แต่ถ้ารันโปรแกรมแล้ว มันจะเปิดหาแฟ้มนี้ไม่เจอครับ เนื่องจาก เรา Add แฟ้มนี้เข้ามาที่ Source Directory ไม่ใช่ output directory ที่อยู่ใต้ bin\debug อีกทีหนึ่ง พอรันโปรแกรม มันเลยหาแฟ้มไม่เจอ ทางแก้ทางแรก ก็คือ copy แฟ้มนี้เข้าไปที่ bin\debug (แล้วจะ Add Existing มาทำไม?) วิธีนี้ไม่ดีครับ เพราะถ้ามีอะไรเปลี่ยนแปลงที่แฟ้มนั้น คุณต้องไปปรับปรุงที่ bin\debug ด้วย ทางแก้ที่สองคือให้เขียน Script ครับ ทุกครั้งที่ build สำเร็จ ให้มัน copy แฟ้มที่ source ไปที่ bin\debug ด้วยเลย ให้ไปที่ Properties ของ Project ครับ เลือก Build Events แล้วก็ไปที่ post-build event command line แล้วให้พิมพ์ดังนี้ครับ copy /Y $(ProjectDir)\nwind.mdb $(TargetDir) ก็จะแก้ปัญหานี้ได้ ส่วน VS.NET 2005 ไม่ต้องทำครับ

    จากนั้นให้ Add New Item เข้าไปที่ Project ครับ แล้ว Add Application Configuration File ผลลัพธ์คุณจะได้แฟ้ม App.Config ภายในเขียนภาษา XML จากนี้ให้คุณลอกข้อมูลทั้งหมดจาก App.Config ใน directory Configuration ของ Gentle.NET ที่ unzip มา เอามาใส่ไว้ใน App.Config ของ Project

มา Config Database กัน

    แฟ้ม App.Config เมื่อ Build แล้ว มันจะถูกเปลี่ยนชื่อเป็น ???.exe.Config  โดยที่ ??? ก็คือชื่อของ Project นั่นเอง โดยปกติแล้วแฟ้มนี้เอาไว้เก็บค่าค่าคงที่ต่างๆ ที่มีใช้ในโปรแกรม ถ้าคุณไม่ต้องการ Hard-code ไว้ในโปรแกรม คุณเอามาเก็บไว้ที่นี่ครับ นี่ก็เช่นกัน การที่ Gentle.NET จะรู้ว่าคุณจะติดต่อฐานข้อมูลยี่ห้อใด database ชื่ออะไร user/password คืออะไร ข้อมูลเหล่านี้ไม่ควร Hard-code ในโปรแกรมครับ เอามาเก็บไว้ที่ App.Config ดีกว่า เมื่อเข้าใจแล้ว เราก็จะมาปรับข้อมูลให้เข้ากับงานเราครับ ให้เราเปลี่ยนบรรทัด 78 จาก

    <DefaultProvider name="SQLServer" connectionString="data source=127.0.0.1;initial catalog=Northwind;user id=mm;password=xxx;Connection Reset=false;packet size=4096" />
   
    ให้เป็น

    <DefaultProvider name="Jet" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=nwind.mdb"/>

    เชื่อว่าทุกคนใช้ ADO หรือ ADO.NET กันมาอย่างโชกโชนแล้ว คงไม่ต้องอธิบายอะไรในส่วนนี้นะครับ จริงๆ แล้ว Gentle.NET ก็เรียกใช้ ADO.NET อีกทีครับ

    จากนั้นเราลบ provider ที่ไม่จำเป็นออก ตั้งแต่บรรทัดที่ 93 ลงมาครับ ถ้า provider ใดไม่ได้ใช้ คือไม่ได้ reference มา ให้ลบทิ้งออกไป ในกรณีนี้เหลือเพียง Jet Provider ไว้ครับ

Mapping Table to Class

    เมื่อเตรียมการทุกอย่างได้แล้ว มาถึงหัวใจการทำ O/R Mapping แล้ว นั่นก็คือการ Mapping นั่นเอง ผมขอเริ่มจาก โครงสร้างของ Table Customers ก่อน

    มาถึงขั้นนี้ เรามาตกลงกันก่อน ถ้าผม Map ทุก Field มันจะทำให้บทความนี้มี Code ที่ยาวเกินไป ผมเอาฉบับย่อก็แล้วกัน ขอ Map เพียงแค่ 3 fields ก็พอ ผมเลือก CustomerID, CompanyName และ ContactName ซึ่งเขียนมาเป็น Class แบบ Gentle.NET ได้ดังนี้

    ผมหันมาใช้ Class Diagram ของ VS.NET 2005 สะดวกกว่าครับ ไม่ต้องเหนื่อยวาดเองใน Visio มีข้อสังเกตครับ ชื่อ Fields ของใน ฐานข้อมูล และ ใน Properties ของ Class นั้นไม่เหมือนกัน (เวลา Gentle.NET เอาข้อมูลไปใส่ ก็ผ่านพวก Properties เหล่านี้ครับ) หรือพูดได้ว่าไม่ควรจะเหมือนกันด้วยซ้ำไป เพราะต่างฝ่ายต่างมีมาตรฐานของตัวเอง จึงเป็นเรื่องธรรมดาอยู่แล้วครับ ที่คุณต้อง Map แบบไม่ตรงกันเช่นนี้ครับ ตรงนี้เอง ที่ทำให้เครื่องมือแต่ละเจ้าแข่งขันกันหาวิธีการทำอย่างไรถึงจะ Map ได้สะดวกที่สุด ทางฝั่งของ Java มักเสนอวิธีการสร้าง แฟ้ม XML เพื่อนิยามการ Mapping ผมเข้าใจเอาเองว่า ที่เลือก XML กันเป็นส่วนใหญ่นั้น เพราะคิดว่าในอนาคต จะสร้างเครื่องมือที่เป็น Graphics Tools มอง class อยู่ด้านซ้าย มอง Table อยู่ด้านขวา แล้วลากเส้นเชื่อมกัน Field ต่อ Field ถ้าใครเคยใช้ DTS ของ MS SQL Server คงจินตนาการภาพนี้ออกอย่างชัดเจน แต่น่าเสียดายครับ สุดท้ายเครื่องมือส่วนใหญ่ก็ไปไม่ถึงจุดนั้นครับ คือไม่มี GUI Editor หรือถ้ามี คุณภาพก็แย่เต็มทน ทิ้งให้เราต้องวุ่นวายเขียน XML กัน (แต่เรื่องนี้ถ้าไปถามคน Java เขาจะบอกว่า XML เป็นเรื่องธรรมชาติ ใช้จนชินจนไม่รู้สึกว่าวุ่นวายแต่อย่างใด) ตัว GUI Editor ที่ใช้ได้ของทางฝั่ง Java ก็ Top Link ของ Oracle นั่นแหละครับ แต่ผมเชื่อว่าคงถูก ObjectSpaces ของ Microsoft แซงเอาในอนาคตอันใกล้ในเรื่องของความง่าย

    Gentle.NET ไม่ได้ใช้แฟ้ม XML สำหรับการ Map แต่หากใช้ Attributes แทน ดังนี้ครับ

[TableName("Customers")]
class Customer
{
   private string _id;
   private string _name;
   private string _contact;

   [TableColumn("CustomerId"),PrimaryKey(AutoGenerated=false)]
   public string Id
   {
      get { return _id; }
      set { _id = value; }
   }

   [TableColumn("CompanyName", NotNull=true,)]
   public string Name
   {
      get { return _name; }
      set { _name = value; }
   }

   [TableColumn("ContactName", NotNull=true)]
   public string Contact
   {
      get { return _contact; }
      set { _contact = value; }
   }
}

    จำได้ไหมครับใน App.config เราเลือก Database ทำ Connection String เรียบร้อยแล้ว มาในขั้นนี้ เราสร้าง Class Mapping โดยการระบุ Attribute ตัวต่อตัวกัน เลย ที่ระดับ class ก็บอกว่า Map กับ Table อะไร ที่ระดับ Property ก็บอกเลยว่า Map กับ Field อะไร เท่านี้เองครับสำหรับการ Map โดยส่วนตัวผมเองแล้ว จะใช้การ Map แบบ Attributes แบบนี้ หรือ จะเป็นแฟ้ม XML ผมก็ไม่มีปัญหา แต่ถ้าเป็น GUI ผมรู้สึกไม่ศรัทธาวิธีนี้เลยจริงๆ ครับ

    ข้อนอกเรื่องนิดหน่อย ทางฝั่ง Java เขาตื่นตัวคำว่า POJO มากครับ มันมาจากคำว่า Plain Old Java Object ความหมายก็คือ เขียน class กันแบบเดิมๆ เอาไปใช้ที่ไหนก็ได้ ไม่มีข้อจำกัด คำนี้ที่มันดังขึ้นมาได้ เหตุผลหลักข้อหนึ่งครับก็คือตัวของ EJB ใน Java ถ้าคุณต้องการใช้งานมัน คุณจะถูกบังคับให้ Implement interfaces ต่างๆ จนมันเสียความเป็น POJO ไป แต่เหตุการณ์ดีขึ้นเยอะครับ ผมทดลอง EJB 3.0 draft บน JBOSS ดูแล้ว มันมีความเป็น POJO ดีขึ้นมาก กลับมาเรื่องของเราต่อครับ ในส่วน code ข้างบนนี้ สักวันหนึ่งถ้าคุณต้องการย้ายฝั่งไปใช้ NHibernate คุณไม่ต้องแก้อะไรเลยครับ เพราะมันเป็น POCSO (Plain old C# Object) ในส่วน Attributes ที่เพิ่มขึ้นมาไม่เป็นปัญหาแต่อย่างใดครับ มองมันเป็น Comment ไปก็ได้ NHibernate ไม่ได้ไปสนใจมันครับ

 มาลอง Load ข้อมูลกันดู

IList list = Broker.RetrieveList(typeof(Customer));

foreach (Customer c in list)
{
System.Console.WriteLine(c.Name);
}

    Code นี้อยู่เป็นบรรทัดแรกใน Main() เลยนะครับ   

    ง่ายๆ แค่นี้ครับ เราใช้คำสั่งเพียงบรรทัดเดียวในการดึงข้อมูล ถ้าเป็นเครื่องมือตัวอื่นต้องเรียกหลายบรรทัด ตั้งแต่การอ่าน config file ไปจนกระทั่ง Connect Database แล้วค่อยมาดึงข้อมูล ส่วน Gentle.NET มาถึงไม่พูดพล่ามทำเพลง เรียกคำสั่งดึงข้อมูลกันเลย Broker ในที่นี้นับได้ว่าตัวรวมรวมงานให้เราใช้ได้อย่างสะดวกไม่ต้องจำอะไรมาก เอะอะอะไรก็เรียก Broker เอาไว้ก่อน แบบนี้ตรงกับ Design Pattern ที่ชื่อว่า Fašade ครับ

    จะเห็นว่าเราขอให้ Broker ดึง Object อะไรก็ได้ที่มีชนิด Customer ออกมาให้หมด  ดังที่เห็นใน foreach นั่นแหละครับ เราเรียกใช้ Customer object เลย ไม่ต้องสนใจคำสั่ง SQL แต่อย่างใด

    ผมลืมบอกไปเราต้อง using library มาก่อนครับ มิฉะนั้น Compile ไม่ผ่าน

using Gentle.Framework;

    แต่มาถึงขั้นนี้ผมควรจะรันโปรแกรมได้แล้ว แต่ก็เกิด Error ครับ ผมพยายามแก้อยู่ครึ่งชั่วโมงแล้ว ก็ไม่ออก ยอมแพ้ครับ เลยลองปรับ Driver ให้เป็น MS SQL Server ดังนี้ครับ  (ใน App.Config)

    <DefaultProvider name="SQLServer" connectionString="data source=(local);initial catalog=northwind;user id=sa;password=sa;packet size=4096" />

    จากนั้นเอา Provider ของ SQLServer ที่บรรทัด 93 ถ้าจำ syntax ไม่ได้ให้ดูเทียบกับ App.Config ของ ใน Gentle.NET ครับ แล้วอย่าลืม Reference เอา Assembly Provider ของ SQLServer มาด้วย

    ปรากฏว่าทำงานได้หน้าตาเฉยเลยครับ ผมอาจจะเข้าใจอะไรผิดเกี่ยวกับ Access ก็ได้ Access ยังคงเป็นอาถรรพ์สำหรับผมอยู่ แต่ไม่เป็นไร เกิดปัญหานี้ก็ดีเหมือนกันครับ ทำให้เราเห็นว่า เราสามารถเปลี่ยนจาก Access ไปเลือก SQL Server หรือ DBMS ยี่ห้ออะไรก็ได้ โดยที่เราไม่จำเป็นต้องแก้ไข Source Code ในส่วนใดเลย ทุกวันนี้เราเจอปัญหาครับ ถึงแม้ว่าเราจะใช้ ADO.NET ที่สามารถเรียกใช้ฐานข้อมูลได้ทุกยี่ห้อก็ตาม แต่ปัญหาก็คือเวลาเราติดต่อฐานข้อมูลใดๆ เราก็ต้องใช้ภาษา SQL version ของ ยี่ห้อนั้น ซึ่งถ้าเขียนง่ายๆ ก็คงจะใช้ทดแทนกันได้ แต่ถ้าเริ่มซับซ้อน ก็ของใครของมันครับ เข้ากันไม่ได้ เชื่อว่าหลายคนคงประสบปัญหา ต้องการย้าย Project งานทั้งหมด จาก Oracle ไปยัง MS SQL Server หรือในทางกลับกัน หรือต้องการเปลี่ยนจากฐานข้อมูลยี่ห้อหนึ่งไปยังอีกยี่ห้อหนึ่ง ตัว Code โปรแกรมโดยเฉพาะอย่างยิ่งในส่วนของ SQL ต้องเอามารื้อใหม่ทั้งหมด แต่ถ้าใช้ Gentle.NET ตั้งแต่แรก เราเปลี่ยนแค่เปลี่ยนใน App.Config (แต่นั่นต้องหมายความว่า Gentle.NET ต้องรองรับงานที่ต้องการทำได้นะครับ ซึ่งผมไม่กล้ารับประกันในข้อนี้)

เลือก ค้นหา Object ก็ได้

Key key = new Key(typeof(Customer), true, "Contact", "Hanna Moos");
Customer c = Broker.RetrieveInstance(typeof(Customer), key);

Code นี้ให้หา Object ที่ Contact ที่มีชื่อว่า Hanna Moos

ค้นหาแบบมีเงื่อนไข

SqlBuilder builder = new SqlBuilder(StatementType.Select, typeof(Customer));
builder.AddConstraint(Operator.Like, "Contact", "%res%");
SqlStatement stmt = builder.GetStatement(true);
IList list = ObjectFactory.GetCollection(typeof(Customer), stmt.Execute());

    ผมเกือบอุทานออกมาว่า "น่าเกลียด" จริงๆ แล้ว ในความเห็นของผม ถ้าทำ O/R Mapping คนใช้ไม่ต้องการรู้อะไรเกี่ยวกับ SQL อีก แต่นี้ชื่อ Class ที่ตั้ง SQLBuilder, SqlStatement แบบนี้เข้าตำราเกลียดตัวกินไข่ แต่ก็เอาเถอะครับ ยอมๆ เขาไป โปรแกรมนี้ ใช้ดึง Object ที่มี Contact like "%res%"

Persist Object

    ในโลกของ Object การ save object เพื่อเอาไว้ดึงในอนาคต เราเรียกว่าการ persist object เมื่อ Map กับโลกของ RDBMS แล้ว ก็เห็นได้ว่ามันก็คือการ Insert Record ใหม่นั่นเอง เราทำอย่างนี้ครับ

Customer c = new Customer();
c.Id = "JFK";
c.Name = "John F. Kennedy";
c.Contact = "Lee Harvey Oswald";
Broker.Persist(c);

    สะดวกมากครับ วิธีนี้ เขียนแค่นี้ก็ Save ได้แล้ว ดูเป็นธรรมชาติครับ แต่เดี๋ยวก่อน Code นี้ Compile ไม่ผ่านครับ Broker.Persist() รองรับเฉพาะ Object ที่ implement IPersistent แต่ class Customer ไม่ได้ Implement อะไรเลย แล้วมันจะ Persist อย่างไร ผมลองไปค้นตำราดู เขาบอกว่า เราต้องทำให้ Object ของเรา Persist-aware ก่อน มี 2 วิธี วิธีแรกเอา IPersistent ไป Implement มีหลาย Methods เลยครับที่ต้อง Implement ซึ่งผมก็ไม่รู้ว่า Implment แล้วต้องลง code อะไร วิธีที่สอง ก็คือ แค่ Inherit class Persistent ไว้ที่ Customer ดังนี้ครับ

class Customer : Persistent

    จากนั้นผมลอง compile โปรแกรมใหม่ดู ผ่านฉลุยครับ ไปดูในฐานข้อมูลปรากฏว่าข้อมูลเข้าถูกต้อง fields อื่นๆ ที่ไม่ได้ระบุนั้น ก็เป็น NULL ไปตามระเบียบครับ แต่ยังก่อน ผมยังไม่ยอมผ่านหัวข้อนี้ คุณทั้งหลายครับ ผมขอถอน ขอถอนจริงๆ ถอนคำพูดครับ ที่ว่า Gentle.NET เป็น POCSO (Plain old C# Object) ไม่ใช่แล้วครับ ถ้าคุณต้อง Implement IPersist ยิ่งแล้วใหญ่ ถ้าคุณ inherit มาจาก Persistent แบบนี้มันก็เหมือนกับ Objectivity ที่ผมใช้เป็นต้นแบบตอนเขียน Momento ไม่ดีครับ คุณเสียความสามารถในการ Inhertance ไป เพราะคุณต้องเสียให้กับการ Inherit Persistent แต่จริงๆ แล้วก็ไม่ใช่เรื่องขอขาดบาดตายแต่อย่างใด มันมีทางเลี่ยงครับ ซึ่งผมคงเอาไม่มาพูดในที่นี้

     ผมตัดสินใจแล้ว ผมขอประกาศตัวเลิกสนับสนุน Gentle.NET ตั้งแต่บัดนี้เป็นต้นไป แต่กรรมของผมที่ก่อขึ้นมาแล้ว ผมขอสานต่อให้จบครับ

Update Object

    อันนี้เล่นง่ายครับ เพราะแค่ดึง Object ขึ้นมา แก้ไข แล้วก็ Persist() กลับไปอีกทีก็เป็น Update แล้วครับ

Key key = new Key(typeof(Customer), true, "Id", "JFK");
Customer c = Broker.RetrieveInstance(typeof(Customer), key) as Customer;
c.Name = "John Fitzgerald Kennedy";
Broker.Persist(c);

Delete Object

    อันนี้ก็ไม่มีอะไรครับ ดึง Object ขึ้นมาแล้วก็เรียก Remove() ครับ

Key key = new Key(typeof(Customer), true, "Id", "JFK");
Customer c = Broker.RetrieveInstance(typeof(Customer), key) as Customer;
c.Name = "John Fitzgerald Kennedy";
Broker.Remove(c);

ทิ้งท้าย

    นี่แค่เริ่มต้นครับ ผมแสดงให้เห็นถึงพื้นฐานของการทำ CRUD (Create Retrieve Update Delete) โดยใช้ O/R Mapping ตัวที่ชื่อว่า Gentle.NET ผมเริ่มศึกษามันก็วันนี้เองครับ เวลา 11:00 เป็นเวลาใกล้เคียงกันกับที่ผมเริ่มเขียนบทความฉบับนี้ ขณะนี้เวลา 17:15 แล้ว ผมอยู่กับมันมาเกือบครึ่งวันแล้ว เมื่อครึ่งชั่วโมงที่ผ่านมาผมตัดสินใจแล้วว่า คงไม่ใช้ Gentle.NET เป็นตัวอย่างในการอธิบาย O/R Mapping ต่อไป ผมขอกลับไปที่ NHibernate ดีกว่า ปัญหาของ Gentle.NET ไม่ถึงกับร้ายแรงมาก แต่ถ้าเรามีตัวที่ดีกว่า ก็น่าจะเลือกสิ่งที่ดีที่สุดครับ

    ผมคงต้องออกไปวิ่งสักหน่อยแล้ว เอาไว้กลับมา ให้ผมตรวจทานขัดเกลาคำสักหน่อย ค่ำนี้คงได้ publish ขึ้น Web ครับ

Supoj

3-JUL-05

.. กลับมาแล้วครับ วิ่งไม่ไหว เช้านี้เดินเตะขอบประตูช้ำเลย เดินไม่เป็นไร พอวิ่งก็รู้สึกครับ ไม่เสี่ยงดีกว่า

-------------------------

ปรับปรุง

    1) มีคนแย้งว่าไม่เคยได้ยิน POCSO มีแต่ POCO (Plain Old CLR Object) ผมขอปรับเป็น POCO ตามชาวบ้านก็แล้วกันครับ

    2) Class Customer ต้องอยู่ใน Namespace ใด Namespace หนึ่ง จะอยู่ลอยๆ โดยใช้ Default Namespace ไม่ได้ มิฉะนั้นจะรันโปรแกรมแล้วมี Error

Supoj

6-JUL-05