یادگیری Castle ActiveRecord با مثال – قسمت دوم


قسمت اول

در ادامه می خواهیم امکان فروش کتاب ها را به برنامه خود اضافه کنیم. برای این کار باید یک کلاس برای نگهداری اطلاعات فروش کتاب ها و یک کلاس برای نگهداری اطلاعات فروش مربوط به مشتریان بسازیم. برای درک بهتر می توان گفت کلاس Order اطلاعات صورت حساب مشتری را نگهداری می کند که در این صورت حساب ممکن است یک یا چند OrderItem وجود داشته باشد که هر کدام از این OrderItemها مشخص کننده تعداد یک کتاب مشخص سفارش داده شده توسط مشتری است. کلاس های زیر را به پروژه خود اضافه کنید:

کلاس Order برای نگهداری صورت حساب مشتری (Order.cs) :

[ActiveRecord(Table="Orders", Lazy=true)]
 public class Order: ActiveRecordBase<Order>
 {
 [PrimaryKey(Generator=PrimaryKeyType.Native)]
 public virtual long ID { get; set; }

 [Property(NotNull=true)]
 public virtual DateTime OrderDate { get; set; }

 [Property(NotNull=true)]
 public virtual decimal TotalPrice { get; set; }

[HasMany(typeof(OrderItem), Inverse=true, Lazy=true, Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]
 public virtual IList<OrderItem> Items { get; set; }

 [BelongsTo(Column="CustomerID", NotNull=true)]
 public virtual Customer Customer { get; set; }
 }

کلاس OrderItem برای نگهداری اطلاعات فروش کتاب ها (OrderItem.cs) :

[ActiveRecord(Table="OrderItems", Lazy=true)]
 public class OrderItem: ActiveRecordBase<OrderItem>
 {
 [PrimaryKey(PrimaryKeyType.Native)]
 public virtual long ID { get; set; }

 [BelongsTo(Column="BookID", NotNull=true)]
 public virtual Book Book { get; set; }

 [Property(NotNull=true)]
 public virtual int Count { get; set; }

 [BelongsTo(Column="OrderID")]
 public virtual Order Order { get; set; }
 }

همانطور که مشاهده می کنید هر Order متعلق به یک Customer است که با صفت BelongsTo در تعریف کلاس مشخص شده و دارای یک یا چند OrderItem است که با صفت HasMany تعریف شده است. چند نکته به نظر می رسد که باید بیشتر در موردشان توضیح داده شود :

  • مشخص کردن کلاس به عنوان Lazy از این جهت است که NHibernate بتواند مجموعه ای از اشیای از نوع این کلاس را به صورت Lazy بار گذاری کند. یعنی هر زمانی که نیاز به اطلاعات این کلاس ها بود، NHibernate اطلاعات را از دیتابیس بخواند.
  • NHibernate برای انجام Lazy Loading در سطح یک کلاس احتیاج دارد که شما تمام پراپرتی ها را به صورت virtual تعریف کنید.
  • در رابطه های HasMany و HasAndBelongsToMany نیاز است تا نوع کلاس طرف دیگر رابطه را با آوردن typeof و نام کلاس مورد نظر مشخص کنید. در مورد رابطه های BelongsTo نیازی به مشخص کردن نوع طرف دیگر رابطه نداریم و نوع پراپرتی همان نوع طرف دیگر رابطه است.
  • در رابطه های مختلف می توانید حالت Cascade را نیز مشخص کنید که اگر مثلاً رکورد یک طرف رابطه حذف شد، رکوردهای وابسته به آن در طرف دیگر رابطه حذف شوند تا داده یتیم در سیستم وجود نداشته باشد.
  • مقدار دهی درست Inverse در رابطه ها بسیار مهم است.معمولاً  شما باید Inverse طرفی را true قرار دهید که با صفت HasMany مشخص شده است.
  • استفاده به جا از Lazy=true در صفت رابطه ها باعث بالا رفتن کارایی برنامه شما خواهد شد.

خب تا اینجا تمام کلاس های مورد نیازمان برای ساختن یک برنامه کتاب فروشی را نوشتیم. حالا می توانید یک کلاس دیاگرام به پروژه خود اضافه کنید (با Add New item و انتخاب گزینه ClassDiagram) و تمام کلاس های ایجاد شده را در آن Drag & Drop کنید تا رابطه های میان کلاس ها را به صورت ویژوال مشاهده کنید. تقریباً کارمان با این پروژه به پایان رسیده. بر روی پروژه خود کلیک راست کنید و گزینه Build را بزنید تا Class Library شما ساخته شود.

حالا بر روی Solution کلیک راست کنید و پروژه جدیدی از نوع Windows Application اضافه کنید. فایل های Castle.ActiveRecord.dll و NHibernate.ByteCode.Castle و البته فایل کتابخانه مدل برنامه خود که ساخته اید را به ارجاعت این پروژه اضافه کنید. سپس یک فایل App.config را با کلیک راست بر روی نام پروژه، برگزیدن Add New Item و انتخاب Application Configuration file به این پروژه اضافه کنید و محتویات زیر را به جای محتویات پیش فرض آن کپی کنید:

<?xml version="1.0"?>
<configuration>
 <configSections>
 <section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord"/>
 </configSections>

 <activerecord>

 <config>
 <add key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>

 <add key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
 <add key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
 <add key="connection.connection_string" value="Data Source=.\SQLEXPRESS;Initial Catalog=MyBookStore;Integrated Security=True;Pooling=False"/>

 <add key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"/>
 </config>

 </activerecord>

<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

سپس در پنجره Server Explorer یک دیتابیس جدید به نام MyBookStore بسازید. در اینجا می خواهیم جداول مورد نیاز مدل برنامه خودمان را در یک دیتابیس SQL Server بسازیم. برای این کار فایل Program.cs را باز کنید و به صورت زیر تغییر دهید:

using System;
using System.Windows.Forms;
using System.Configuration;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
using MyBookStore.Model;

namespace MyBookStore
{
 static class Program
 {
 /// <summary>
 /// The main entry point for the application.
 /// </summary>
 [STAThread]
 static void Main()
 {
 Application.EnableVisualStyles();
 Application.SetCompatibleTextRenderingDefault(false);
 IConfigurationSource configSource = ConfigurationManager.GetConfig("activerecord") as IConfigurationSource;
 ActiveRecordStarter.Initialize(configSource, typeof(Book), typeof(Author), typeof(Publisher),
 typeof(Category), typeof(Customer), typeof(Order), typeof(OrderItem));
 ActiveRecordStarter.CreateSchema(); //اینجا دیتابیس از روی کلاس ها ساخته می شود
 Application.Run(new Form1());
 }
 }
}

اگر تمام کار ها را به درستی انجام داده باشید با زدن دکمه F5 دیتابیس شما به صورت زیر ساخته خواهد شد:

Server Explorerهمانطور که مشاهده می کنید به ازای هر یک از کلاس های برنامه ما یک Table در دیتابیس ساخته شده و برای ایجاد رابطه چند به چند میان موجودیت Category و Book نیز یک Table واسط به نام BookCategories ساخته شده است.

برای تنظیم اولیه Castle ActiveRecord چند راه وجود دارد که در اینجا من از IConfigurationSource استفاده کردم و تنظیمات را از فایل کانفیگ برنامه خواندم و به ActiveRecordStarter.Initialize فرستادم. در این متد باید نوع تمام کلاس هایی که قرار است Map شوند را برای CAR مشخص کنید. سپس با استفاده از متد CreateSchema از کلاس ActiveRecordStarter دیتابیس را بر روی SQL Server می سازم. CAR برای انجام این کار از تنظیماتی که در فایل App.config مشخص شده است، استفاده می کند. همانطور که می بینید در تنظیمات مشخص کرده ام که قرار است دیتابیس بر روی SQL Server 2008 با Connection String مشخص شده ساخته شود. البته نوشتن CreateSchema در متد Main برنامه کار درستی نیست. شما باید فقط زمانی دیتابیس را از ابتدا بسازید که دیتابیس برنامه از قبل وجود نداشته باشد. در واقع فقط هنگام نصب برنامه (یا اجرای اول برنامه) دیتابیس باید بوسیله این متد ساخته شود و در دفعات بعدی از آن برای ذخیره و بازیابی داده ها استفاده شود.

اگر بخواهیم Database Diagram یا همان ERD این پروژه را مشاهده کنیم، باید نموداری شبیه به نمودار زیر را داشته باشیم:

MyBookStore ERDدر تصویر بالا می توانید تمام ارتباط هایی که قبلا در کلاس ها تعریف کرده ایم را مشاهده کنید.

دریافت پروژه مثال تا اینجا (لطفاً پس از دریافت، پسوند فایل را به zip تغییر داده و سپس فایل را باز کنید!)

یک نکته : اگر از گوگل ریدر یا هر فیدخوان دیگری استفاده می کنید و کدها را به درستی مشاهده نمی کنید، لطفاً پست اصلی را در وبلاگ بخوانید.

farasun.wordpress.com

این مطلب ادامه دارد…

برای اینکه مطالب بعدی را از دست ندهید، مشترک فید فراسان شوید!

Advertisements