۱۳۸۹/۱۰/۱۳

SQL توليدي در NHibernate از كدام متد صادر شده است؟


اگر مطلب "ذخيره سازي SQL توليدي در NH3" را دنبال كرده باشيد كه يك مثال عملي از "NHibernate 3.0 و عدم وابستگي مستقيم به Log4Net" بود، خروجي حاصل از آن به صورت زير است:
---+ 12/29/2010 05:35:59.75 +---
SQL ...

---+ 12/29/2010 05:35:59.75 +---
SQL ...
و پس از مدتي اين فايل هيچ حسي را منتقل نمي‌كند! يك سري SQL كه لاگ شده‌اند. مشخص نيست كدام متد در كدام كلاس و كدام فضاي نام، سبب صدور اين عبارت SQL ثبت شده‌، گرديده‌ است.
خوشبختانه در دات نت فريم ورك مي‌توان با بررسي Stack trace ، رد كاملي را از فراخوان‌هاي متدها يافت:
StackTrace stackTrace = new StackTrace();
StackFrame stackFrame = stackTrace.GetFrame(1);
MethodBase methodBase = stackFrame.GetMethod();
Type callingType=methodBase.DeclaringType;
با بررسي StackFrame ها امكان يافتن نام متدها، فضاهاي نام و غيره ميسر است. مثلا يكي از كاربردهاي مهم اين روش، ثبت فراخوان‌هاي متدي است كه استثنايي را ثبت كرده است.
بر اين اساس سورس مثال قبل را جهت درج اطلاعات فراخوان‌هاي متدها تكميل كرده‌ام، كه از اين آدرس قابل دريافت است.

اكنون اگر از اين ماژول جديد استفاده كنيم، خروجي نمونه‌‌ي آن به صورت زير خواهد بود:
---+ 01/02/2011 02:19:24.98 +---
-- Void ASP.feedback_aspx.ProcessRequest(System.Web.HttpContext) [File=App_Web_4nvdip40.5.cs, Line=0]
--- Void Prog.Web.UserCtrls.FeedbacksList.Page_Load(System.Object, System.EventArgs) [File=FeedbacksList.ascx.cs, Line=23]
---- Void Prog.Web.UserCtrls.FeedbacksList.BindTo() [File=FeedbacksList.ascx.cs, Line=43]
----- System.Collections.Generic.IList`1[Feedback] Prog.GetAllUserFeedbacks(Int32) [File=FeedbackWebRepository.cs, Line=66]

SELECT ...
@p0 = 3 [Type: Int32 (0)]
به اين معنا كه عبارت SQL ثبت شده، حاصل از پردازش صفحه‌ي feedback.aspx، سپس متد Page_Load آن كه از يوزر كنترل FeedbacksList.ascx استفاده مي‌كند، مي‌باشد. در اينجا فراخواني متد BindTo سبب فراخواني متد GetAllUserFeedbacks در فايل FeedbackWebRepository.cs واقع در سطر 66 آن گرديده است.
اينطوري حداقل مي‌توان دريافت كه SQL توليدي دقيقا به كجا بر مي‌گردد و چه متدي سبب صدور آن شده است.

ملاحظات:
اين ماژول تنها در صورت وجود فايل pdb معتبر كنار اسمبلي‌هاي شما اين خروجي مفصل را توليد خواهد كرد. در غير اينصورت از آن صرفنظر مي‌كند. (براي مثال نام فايل سورس فراخوان، شماره‌ي سطر فراخوان، حتي محل قرارگيري آن فايل بر روي كامپيوتر شما در فايل‌هاي pdb ثبت مي‌گردند؛ به همين جهت توصيه اكيد حين ارائه‌ي نهايي برنامه، حذف اين نوع فايل‌ها است)