عشان تبدأ أي شغل مع الداتابيز، لازم الأول تعمل 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). المهم إن الـ dbContext object جاهز للتعامل.

الـ 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.
  • إيه اللي بيحصل؟ الـ using statement دي هي مجرد Syntax Sugar. يعني شكل كتابة مختصر ومريح، لكن الـ compiler في الآخر بيحولها وراك لكود شبه الـ try...finally اللي فوق ده عشان يضمن إن Dispose() تتنادى في كل الحالات (سواء الكود خلص طبيعي أو حصل exception).

  • إمتى بيقفل؟

    • في الشكل الأول (بتاع الـ {}): الـ Dispose() بتتنادى أول ما الكود يوصل للقوس الأخير } بتاع الـ using بلوك.
    • في الشكل التاني (من غير {}): الـ Dispose() بتتنادى في آخر الـ scope (النطاق) اللي الـ dbContext متعرف فيه (يعني غالبًا في آخر الـ method اللي إنت فيها).

الخلاصة: دايمًا استخدم using مع الـ DbContext (ومع أي object بيطبق IDisposable) عشان تضمن إن الـ resources (زي الـ database connection) بتتقفل صح وبشكل آمن، وتتجنب تسريب الموارد ومشاكل الأداء.