مشکلات پیش رو پس از راهاندازی Lazy Loading در NHibernate
در نسخه جدید NHibernate رفتار پیشفرض برای بارگذاری دادهها استفاده از روش Lazy Loading است و تا زمانی که به سطحی از دادهها نیاز نداشته باشیم، آن سطح از دادهها در حافظه بارگذاری نخواهد شد.
راهاندازی Lazy Loading بدون مدیریت درست آن ممکن است باعث بروز خطاهایی در بارگذاری و استفاده از دادهها در برنامه ما شود. این عبور موجب به وجود آمدن برخی استثنائات در برنامه خواهد شد، لذت در هنگام استفاده از آن باید به دقت عمل نمود. از مشکلات پیش رو میتوان به موارد زیر اشاره کرد:
۱- بارگذاری نشدن دادههای مرتبط با آبجکت مورد نظر ما:
به عنوان مثال در نمونه روبرو اگر دادههای مربوط به کلاس Order را در حافظه بارگذاری نماییم یا به طور دقیقتر اگر
توسط متد Get یک سفارش (order) را از پایگاه داده خوانده و در حافظه قرار دهیم و session را ببندیم، در این صورت در هنگام فراخوانی یکی از مشخصههای مرتبط با کلاسهای مرتبط با این کلاس با خطا مواجه خواهیم شد. مثلا برای اجرای این خط از کد
string name = Order.Customer.CompanyName;
با خطا مواجه خواهیم شد. دلیل این است که در Lazy Loading و در اجرای متد Get کوئری ساخته شده دارای هیچ join ای با هیچ کدام از جداول معادل کلاسهای دیگر نیست و عملا ما به دادههای کلاسهای دیگر دسترسی نداشتهایم.
۲- مشکل n + 1 عبارت select :
اگر پس از بارگذاری یک Order بخواهیم به آیتمهای OrderLine دسترسی پیدا کنیم، در این صورت به ازای هر آیتمی که به آن دسترسی پیدا میکنیم یک عبارت select ساخته میشود. بنابراین اگر دارای n آیتم باشیم و بخواهیم به تمام آنها دسترسی پیدا کنیم، یک عبارت select برای خود order و n عبارت برای تمام آیتمهای مرتبط با آن ساخته میشود که در نتیجه دارای n+1 عبارت select خواهیم بود (دلیل نامگذاری). این امر میتواند عملیات واکشی دادهها را کند نماید و سبب سرباری روی وایگاه داده میشود.
فرض کنید دارای یک collection هستید که دارای چند صد آیتم باشد و ما فقط نیاز به دسترسی به یک یا دو مورد از آنها هستیم. اگر بخواهیم تمام آیتمها را بارگذاری کنیم مقادیر زیادی از منابع خود را از دست خواهیم داد اما خوشبختانه NHibernate دارای راه حلی برای این مورد است، این راه حل Eager Loading نام دارد.