عشان تبدأ أي شغل مع الداتابيز، لازم الأول تعمل 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
) بتتقفل صح وبشكل آمن، وتتجنب تسريب الموارد ومشاكل الأداء.