عشان تبدأ أي شغل مع الداتابيز، لازم الأول تعمل object من الـ DbContext بتاعك اللي جهزناه قبل كده. مجرد ما بنعمل الـ object ده، هو بيكون جاهز يفتح connection لما يحتاجه.
// Main method or wherever you need database access
using CompanyDbContext dbContext = new CompanyDbContext();
// OR older style: using (CompanyDbContext dbContext = new CompanyDbContext()) { /* ... */ }- كدة فتحنا Connection؟ لأ مش بالظبط لسه. الـ DbContext بيحضر نفسه، لكن الـ connection الفعلي للداتابيز غالبًا بيتفتح أول ما تيجي تعمل أول عملية محتاجاه (زي query أو
SaveChanges). المهم إن الـdbContextobject جاهز للتعامل.
الـ Connection ده لازم يتقفل! (Managing Resources)
الكود بتاع الـ C# بنسميه Managed Code. يعني إيه؟ يعني فيه حاجة اسمها CLR (Common Language Runtime) هي المسئولة عن إدارة الذاكرة والحاجات دي، زي إنها بتشيل الـ objects اللي مبقتش مستخدمة عن طريق الـ Garbage Collection.
بس فيه حاجات الـ CLR مش بتعرف تديرها لوحدها، بنسميها Unmanaged Resources. زي إيه؟ زي الـ database connection اللي فتحناه، أو التعامل مع files، أو network streams. الحاجات دي لو فتحتها، لازم تتأكد إنك بتقفلها بنفسك عشان متعملش مشاكل وتسرب resources.
الطريقة القديمة: try...finally
زمان، كنا عشان نضمن إن الـ resource ده يتقفل حتى لو حصل error، بنستخدم try…finally ودا اللي بنسميه Exception Handling:
// Old way - Generally avoid this for DbContext, prefer 'using'
CompanyDbContext dbContext = null;
try
{
dbContext = new CompanyDbContext();
// --- Do CRUD Operations Here ---
// Example: dbContext.Employees.Add(new Employee { Name = "Test" });
// dbContext.SaveChanges();
}
finally
{
// This block ALWAYS executes, ensuring Dispose is called
if (dbContext != null)
{
// Manually dispose the context to release the connection and other resources
dbContext.Dispose(); // The key method for cleanup
}
}- الـ
Dispose()methodدي هي المسئولة عن تحرير الـunmanaged resources(زي قفل الـconnection). أيclassبيتعامل معunmanaged resourcesالمفروض يوفر الـmethodدي عن طريق تطبيقinterfaceاسمه IDisposable.
الطريقة الحديثة والأحسن: using Statement
الـ C# بتقدملنا طريقة أحسن وأنضف بكتير عشان نتعامل مع الـ objects اللي محتاجة Dispose (اللي بتطبق IDisposable، والـ DbContext واحد منهم). الطريقة دي هي الـ Cs Using statement.
-
الشكل الأول (Block Scope):
// Recommended way (Block scope) using (CompanyDbContext dbContext = new CompanyDbContext()) { // --- Do CRUD Operations Here --- // Example: var employees = dbContext.Employees.ToList(); // The code inside the block has access to dbContext } // <--- At this closing brace '}', dbContext.Dispose() is AUTOMATICALLY called! // Resources (like the DB connection) are released here, even if an exception occurred inside the block. -
الشكل التاني (Declaration Scope - الأحدث والأكثر اختصارًا):
// Recommended way (Declaration scope - C# 8.0 and later) using CompanyDbContext dbContext = new CompanyDbContext(); // --- Do CRUD Operations Here --- // Example: var employees = dbContext.Employees.ToList(); // ... more code within the same scope ... // <--- At the end of the CURRENT SCOPE (e.g., end of the method), // dbContext.Dispose() is AUTOMATICALLY called! // Resources are released here, even if an exception occurred earlier in the scope. -
إيه اللي بيحصل؟ الـ
usingstatementدي هي مجرد Syntax Sugar. يعني شكل كتابة مختصر ومريح، لكن الـcompilerفي الآخر بيحولها وراك لكود شبه الـtry...finallyاللي فوق ده عشان يضمن إنDispose()تتنادى في كل الحالات (سواء الكود خلص طبيعي أو حصلexception). -
إمتى بيقفل؟
- في الشكل الأول (بتاع الـ
{}): الـDispose()بتتنادى أول ما الكود يوصل للقوس الأخير}بتاع الـusingبلوك. - في الشكل التاني (من غير
{}): الـDispose()بتتنادى في آخر الـscope(النطاق) اللي الـdbContextمتعرف فيه (يعني غالبًا في آخر الـmethodاللي إنت فيها).
- في الشكل الأول (بتاع الـ
الخلاصة: دايمًا استخدم using مع الـ DbContext (ومع أي object بيطبق IDisposable) عشان تضمن إن الـ resources (زي الـ database connection) بتتقفل صح وبشكل آمن، وتتجنب تسريب الموارد ومشاكل الأداء.