ساخت، load و ذخیره کردن آبجکتها در NHibernate
ITransaction tx;
try
}
session = factory.OpenSession();
tx = session.BeginTransaction();
// do database work
tx.Commit();
session.Close();
{
catch (Exception ex(
}
tx.Rollback();
session.Close();
// further exception handling
{
نویسندگان مستندات Hibernate مصرانه پیشنهاد میکنند که هرگز یک exception را بازیابی نکنید زیرا بازیابی تراکنش به عنوان اولین قدم در handle کردن Exception ها در ابتدای برنامه قرار دارند. این خیلی مهم است زیرا NHibernate به صورت آبشاری مدیریت می کند.
جایی که به مشکل بخورند خودشان را نشان میدهند. بهترین نظر این است که همه چیز را به حالت اول برگردانید، در دامنه مدلتان مشکل را حل کنید و دوباره سعی کنید.
بگذارید راجع به انواع رایج فعالیتها برای object های ماندگارمان صحبت کنیم. خب، دیدید که پیادهسازی سه متد اول interface DBMgr در بالا نمایش داده شد.متد getDepartments() لیستی از بخش های ِDepartment را برمی گرداند.
{
IList depts = null;
try
{
ISession session = factory.OpenSession();
ITransaction tx = session.BeginTransaction();
depts = session.CreateCriteria(typeof(Department)).List();
session.Close();
}
catch (Exception ex)
{
tx.Rollback();
session.Close();
// handle exception.
}
return depts;
}
آبجکت session نشان میدهد متد createcriteria() که به عنوان آرگومان، یک نوع کلاس پایدار را میگیرد. این نشان میدهد که NHibernate با تبدیل های مپ شده به آبجکت ها فعل و انفعالها را تندتر میکند. در نتیجه list() نتایج برگشتی از تمامی interface های موجود را برمیگرداند. در این مورد بهتر است یک لیست شامل خواصی از Department را برگردانیم.که با دیتابیس کاملا یکی است (شامل تمام دیگر آبجکت های مرتبط با department). این متد صریحی است که استفاده میشود که در دیتابیس شما در میان تمام interface های کلاس تکرار میشود.
اگر شما می خواهید interface مشخصی از database را تکرار کنید شما باید مقادیر مشخص از شناسه فیلدها را برای کلاس هدف بدانید که شما دنبال آن هستید.
{
Department d = null;
try
{
ISession session = factory.OpenSession();
ITransaction tx = session.BeginTransaction();
d = (Department)session.Load(typeof(nhRegistration.Department), i);
session.Close();
}
catch (Exception ex)
{
tx.Rollback();
session.Close();
// handle exception. }
return d;
}
فقط به خاطر داشته باشید که نتایج session.load() را به یک نوع مناسب object ای که برمیگرداند cast کنید.
در پایان آیا میخواهید تغییرات را در یک interface ذخیره کنید (یا یک interface جدید ایجاد کنید)؟ آیا session در متد برای شما session.save() را که برای ایجاد یک interface جدید به کار میرود در نظر گرفته است یا session update() که برای تغییر یک interface از session موجود به کار می رود؟ شما مجبورید که این دو را جدا در نظر بگیرید. اگر شما یک متد اشتباه را اجراکنید. تداخل session و خطاهای پایگاه داده رخ میدهد ، در interface ما با وجود اینکه پیادهسازی DBmgr فقط یک متد saveDepartment(Department dept) را دارد. این برای یک برنامۀ ساده عقلانی نیست که برنامه نویسان مجبور شوند بین ماندگار کردن یک object جدید و یک object از پیش موجود تفاوت قایل شوند به همین دلیل interface ما فقط یک متد دارد. در پیادهسازی ما هنوز نیازمند این تفلوت قایل شدن هستیم.
{
try
{
ISession session = factory.OpenSession();
ITransaction tx = session.BeginTransaction();if(dept.Id == 0)
{
session.Save(dept);
}
else
{
session.Update(dept);
}
tx.Commit();
session.Close();
}
catch (Exception ex)
{
tx.Rollback();
session.Close();
// handle exception
}
}
ابتدا پیش از آنکه interface را ماندگار کنیم باید این را تشخیص دهیم که آیا از پیش وجود دارد یا اینکه جدید است. بوسیلۀ یک فیلد ساده تشخیص هویت integer ی، ما فقط ارزیابی میکنیم که مقدار آن صفر است یا نه. که این معنی را میدهد که هیچ ردیفی از قبل در پایگاه داده وجود ندارد. (صفت ثبت نشده را در بالا به یاد بیاورید). شما میتوانید تصور کنید که این منطق، کاربردی در تشخیص هویتهای پیچیده ندارد، هنگامیکه ما در مورد از پیش وجود داشتن interface تصمیمگیری میکنیم، متد جدیدی را در session برای این کار در نظر میگیریم.