ไม่ต้องเสียเวลาโม้มาก สั้นๆ ง่ายๆเลยแล้วกัน
Castle ActiveRecord เป็นโปรแกรมที่(ลอก)ได้แรงบันดาลใจมาจาก Active Record ที่ใช้ใน Ruby On Rails ซึ่งเอาแนวคิดมาจาก Martin Fowler อีกที จุดมุ่งหมายคือต้องการสร้าง O/R mapper ที่ใช้งานได้ง่ายให้กับ MonoRails ที่เป็นโคลนของ RoR บน .NET ตัว ActiveRecord เองจริงๆแล้วก็สร้างขึ้นมาบน NHibernate อีกที ถึงแม้ว่า ActiveRecord จะถูกสร้างขึ้นมาสำหรับ MonoRails แล้ว แต่เราก็ดึงเอาแค่ ActiveRecord ออกมาใช้งานเฉยๆก็ย่อมได้เช่นกัน
กลไกการทำงานทั่วๆไปของ ActiveRecord ก็คือจะแทน 1 คลาส = 1 ตาราง และให้แต่ละอ็อปเจกต์แทนแถวของตาราง โดยจะใช้การประกาศแอทริบิวต์แทนการสร้าง Mapping File ของ NHibernate
จากตัวอย่างการประกาศคลาส User
using System;
using Castle.ActiveRecord;
[ActiveRecord]
public class User : ActiveRecordValidationBase<User>
{
[PrimaryKey(PrimaryKeyType.Native)]
public virtual int ID { get; set; }
[Property]
public virtual string Email { get; set; }
[Property]
public virtual string Password { get; set; }
}
เริ่มมาก็ทำการประกาศคลาส User โดย inherit จาก ActiveRecordValidationBase
ในการแทนฟิลด์แต่ละฟิลด์จะใช้ Property ซึ่งในเอกสารบอกว่าควรจะทำเป็น Virtual Property ไว้จะดีกว่าเพราะจะสนับสนุนการทำ Lazy Loading ให้ในตัว แล้วก็ต้องไม่ลืมกำหนดแอททริบิวต์ Property ด้วย
ทีนี้ในการใช้งานเราก็จะต้องบอกว่าให้ไปใช้ฐานข้อมูลไหน ในที่นี้ขอยกตัวอย่างเป็นเว็บแอพพลิเคชัน ก็จะไปตั้งค่าที่ web.config แล้วเพิ่ม section นี้เข้าไปใน element config section
<configSections>
<section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord"/>
</configSections>
จากนั้นก็ใส่ element activerecord ลงไปเพื่อกำหนด connection และค่าต่างๆ จากตัวอย่างคือนำไปใช้กับ MySQL แต่ถ้าหากอยากใช้กับฐานข้อมูลอื่นๆ ให้ดูจากหน้า การใช้งาน NHibernate กับฐานข้อมูลอื่นๆ
<activerecord>
<config>
<add
key="hibernate.connection.driver_class"
value="NHibernate.Driver.MySqlDataDriver" />
<add
key="hibernate.dialect"
value="NHibernate.Dialect.MySQLDialect" />
<add
key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider" />
<add
key="hibernate.connection.connection_string"
value="Database=ar;Data Source=localhost;User Id=root;Password=mysql" />
</config>
</activerecord>
ทีนี้เวลาใช้งาน ก็จะต้องมีการเรียก Active Record เพื่อเริ่มทำงาน ตรงนี้ผมใช้วิธีการสร้างเป็นคลาสที่ inherit มาจากคลาส HttpApplication ขึ้นมาอีกคลาส เมื่อแอพพลิเคชันเร่ิมทำงานให้เริ่มการทำงานของ ActiveRecord ด้วยโดยใช้ค่าต่างๆจาก web.config ที่ตั้งค่าไว้เมื่อกี้ แล้วให้สร้าง Session Scope ของ ActiveRecord ขึ้นมาตอนเริ่ม Request และทำลายทิ้งเมื่อจบ Request
using System;
using System.Web;
using System.Web.Security;
using System.Web.Configuration;
using Castle.ActiveRecord.Framework;
using Castle.ActiveRecord;
public class GlobalApplication : HttpApplication
{
private const string STR_Arsessionscope = "ar.sessionscope";
public GlobalApplication()
{
this.BeginRequest += new EventHandler(GlobalApplication_BeginRequest);
this.EndRequest += new EventHandler(GlobalApplication_EndRequest);
}
void GlobalApplication_EndRequest(object sender, EventArgs e)
{
try
{
SessionScope scope = HttpContext.Current.Items[STR_Arsessionscope] as SessionScope;
if (scope != null)
{
scope.Dispose();
}
}
catch (Exception ex)
{
HttpContext.Current.Trace.Warn("Error", "EndRequest: " + ex.Message, ex);
}
}
void GlobalApplication_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items.Add(STR_Arsessionscope, new SessionScope());
}
public void Application_Start()
{
IConfigurationSource source =
WebConfigurationManager.GetSection("activerecord") as IConfigurationSource;
InitActiveRecord(source);
}
public static void InitActiveRecord(IConfigurationSource source)
{
ActiveRecordStarter.Initialize(source,
typeof(User)
)
;
}
}
ตรงนี้จะใช้ความถึกเล็กน้อยคือจะต้องบอกตัว ActiveRecordStarter ให้หมดว่าเราจะให้คลาสไหนบ้างที่ทำหน้าที่เป็น ActiveRecord
เสร็จแล้วถ้าเรารันตอนนี้เลยก็ยังใช้งานไม่ได้ จะต้องวิ่งไปบอก Global.asax ให้มา inherit จากคลาสนี้แทนก่อน หลังจากเพิ่ม Global.asax เข้าใน project แล้วก็เปิดแก้ตรงด้านบนเป็น
<%@ Application Language="C#" Inherits="GlobalApplication" %>
ทีนี้ก็ลองสร้าง web form ขึ้นมาทดสอบดู
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
<asp:BoundField DataField="Password" HeaderText="Password"
SortExpression="Password" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="FindAll" TypeName="User"></asp:ObjectDataSource>
จากข้อมูลที่มีแบบนี้
ก็เอามาแสดงเป็นแบบนี้ได้
เป็นอันว่าสำหรับไปหนึ่งขั้น เจอกันใหม่ตอนหน้า



Comments
Post new comment