استفاده صحیح از DbContext و فراخوانی متد Dispose در EF

پرووید

دسته های مقالات

در این آموزش از وب سایت پرووید در رابطه با کار کردن با شی DbContext و
به طور خاص مبحث Connection ها صحبت می کنیم.

در رابطه با کار کردن با شی DbContext دو روش کلی برای ساختن این شی وجود
دارد. در روش اول شما زمانی که یک شی از کلاس اصلی ‌تان ساخته می شود شی DbContext را هم می سازیدِ این کار می‌تواند
از طریق تعریف یک فیلد Private در درون کلاس و Initialize کردن آن در تابع سازنده کلاستان انجام شود. تعریف شی به
عنوان فیلد را در قسمت زیر می بینید.

 
Public Class Customer Repository
Dim db As New CustomerEntities

و در این قسمت Initialize کردن شی DbContext را در تابع سازنده کلاس
مشاهده می کنید.

 
Public Class Customer Repository
Dim db As CustomerEntities

Public Sub New()
db = New CustomerEntities
End Sub

از این روش اغلب زمانی استفاده می شود که تمامی متد های درون یک کلاس از
شی DbContext استفاده می‌کنند و این متدها به صورت مستقل از هم و در ترکیب های مختلفی از یکدیگر فراخوانی می‌شوند.
دقت کنید که اگر در این روش فراموش کنید متعد Dispose را فراخوانی کنید طبیعتاً شی DbContext در حافظه باقی خواهد
ماند.

روش دیگر استفاده از شی DbContext قرار دادن تعریف آن در یک بلاک Using
است. اغلب از این روش زمانی استفاده می شود که کدهای مربوط به Entity Framework با بقیه فرآیندهای مربوط به Entity
Framework یکپارچه شده‌اند. در استفاده از بلاک Using همیشه در پایان این بلاک به صورت خودکار متد Dispose فراخوانی
می شود. در در واقع در استفاده از این روش حتی اگر متد Dispose را بصورت Explicit فراخوانی نکنید شی DbContext در
پایان بلاک Using از حافظ خارج میشود.

نکته دیگری که قصد دارم به آن اشاره کنم این است که در تست‌های
Performance اغلب تفاوت زیادی بین کدی که به صورت Explicit متد Dispose را اجرا میکند با کدی که فراموش میکند این
کار را انجام دهد وجود ندارد. اما این قضیه یک استثنا دارد و آن هم باز کردن Explicit شی Connection درونی DbContext
است. در چنین سناریویی اگر فراموش کنید شی Connection را ببندید DbContext آن را به صورت خودکار نخواهد بست. در واقع
اگر شما اجازه دهید DbContext مسئولیت باز کردن و بستن Connection را به عهده بگیرد این کار را به صورت خودکار انجام
می‌دهد اما اگر به صورت دستی شی Connection را باز کنید باید حتما خود شما آن را ببندید.

حال ممکن است بپرسید که باز گذاشتن شی Connection چه معایبی می تواند
داشته باشد. اگر مبحث مربوط به Connection Pooling را بدانید متوجه منظورم خواهید شد. در واقع در Connection Pooling
یک حوضچه از Connection ها ساخته شده و در زمان بسته شدن یک Connection آن شی Connection به Pool برگردانده می شود.
این موضوع باعث می‌شود که کدهای قسمت های دیگر برنامه شما مجبور نباشند شی Connection جدیدی را بسازند. ساختن شی
Connection یه کار پر هزینه از لحاظ منابع سیستم است. در واقع با استفاده از روش Connection Pooling به جای ساختن شی
Connection جدید از اشیا Connection ی که در حوضچه یا Pool قرار گرفته اند استفاده می شود.

پس به عنوان نتیجه ‌گیری اگر به DbContext اجازه می‌دهید که Connection
های شما را مدیریت کند می توانید از فراخوانی متد Dispose صرفنظر کنید اما اگر خودتان به صورت دستی Connection های
درون DbContext را مدیریت کرده و آنها را باز یا بسته می کنید حتما باید در پایان کار از متد Dispose استفاده کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *