نظرة سريعة على Entity Framework
- ما هو Entity Framework
- مميزات Entity Framework
- علاقة Entity Framework و LINQ
- مفهوم
DbSet
وDbContext
في Entity Framework
ما هو Entity Framework
Entity Framework أو EF إختصاراً هو إطار عمل ( Framework ) من مايكروسوفت يُستخدم للتعامل مع قواعد البيانات في مشاريع .NET بطريقة سهلة و عالية المستوى بدلاً من الحاجة إلى كتابة إستعلامات SQL يدوياً.
في لغة C# يمكنك استخدام EF للتعامل مع جداول قواعد البيانات ( Database Tables ) و كأنك تتعامل مع كائنات عادية ( Objects )، و بدوره EF يتولى تحويل العمليات التي تجريها إلى استعلامات SQL بشكل تلقائي.
مميزات Entity Framework
- ORM أو Object-Relational Mapper يربط بين الكائنات في الكود و الجداول في قاعدة البيانات.
- Code First يمكنك إنشاء قاعدة البيانات من الكود مباشرة (من الكيانات).
- Database First يمكنك إنشاء الكود من قاعدة بيانات موجودة مسبقاً.
- Migration System يتيح نقل و تحديث قاعدة البيانات بسهولة عند تعديل الكود.
- يدعم LINQ يمكنك كتابة استعلامات باستخدام LINQ بدلاً من SQL.
علاقة Entity Framework و LINQ
يعتمد EF أسلوب LINQ بشكل أساسي عند التعامل مع قواعد البيانات.
في حال كنت ستكتب إستعلام بلغة SQL فإنه سيبدو كما يلي.
مثال
SELECT * FROM Products WHERE Id = 1
الإستعلام السابق نفسه، يمكن تنفيذه نفسه بشكل مباشر في C# بأسلوب LINQ كما يلي.
مثال
var product = await _context.Products.FindAsync(1);
إذاً EF يتولى تحويل كود LINQ إلى إستعلام SQL و تنفيذه خلف الكواليس.
مفهوم DbSet
و DbContext
في Entity Framework
في تطبيقات .NET التي تستخدم EF كوسيلة للتعامل مع قواعد البيانات، يعتبر الكلاس DbContext
هو حجر الأساس في هذا التفاعل. يمكننا تشبيهه بأنه بمثابة وسيط أو جسر إتصال بين كود التطبيق و قاعدة البيانات، فهو يتولى مسؤولية تنفيذ الاستعلامات، تتبّع التغييرات، و إرسالها إلى قاعدة البيانات عند الحفظ إلخ..
بعبارة أبسط، DbContext
يُمثّل جلسة عمل ( Session ) مع قاعدة البيانات فهو يقوم بإدارة دورة حياة الكيانات ( Entities ) أثناء تنفيذ العمليات مثل الإضافة و التعديل و الحذف دون الحاجة إلى كتابة استعلامات SQL يدوياً.
الكلاس DbContext
يحتوي على خاصية إسمها DbSet<T>
تسمح بتمرير إسم أي كلاس يمثّل كيان ما ليتم تحويله إلى جدول في قاعدة البيانات و ليصبح بالإمكان التعامل معه لاحقاً من خلال الإسم الذي نعطيه للخاصية.
يمكن القول إن DbContext
هو المسؤول الأساسي عن إدارة الاتصال و التعامل مع قاعدة البيانات، في حين أن DbSet
يمثل الواجهة التي نستخدمها للوصول إلى الجداول و التعامل معها كما لو كانت مجموعات بيانات مخزنة في الذاكرة.
إدارة قواعد البيانات بأسلوب EF
1- لإنشاء جدول في قاعدة البيانات، نقوم أولاً بإنشاء كلاس ليمثلّه كما يلي.
مثال
public class Product { public int Id { get; set; } public string Name { get; set; } public Decimal Price { get; set; } }
2- لإعلام EF أن الكلاس Product
هو بمثابة جدول في قاعدة البيانات، نقوم بإنشاء كلاس يرث من DbContext
و فيه نقوم بإضافة خاصية نوعها DbSet<Product>
كما يلي.
مثال
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Product> Products { get; set; } }
إذاً الكلاس AppDbContext
أصبح يمثّل السياق ( Context ) الخاص بالتعامل مع قاعدة البيانات، بمعنى أن أي عملية سنجريها لاحقاُ مع قاعدة البيانات ستتم من خلاله.
في هذا الكلاس، أنشأنا كونستركتور و مررنا له كائن نوعه DbContextOptions<AppDbContext>
لأنها الطريقة التي من خلالها نمرر معلومات الإتصال بقاعدة البيانات إليه.
الكائن الذي تم تمريره للكونستركتور يحتوي على إعدادات مهمة جداً، مثل نوع قاعدة البيانات المستخدمة، و معلومات الإتصال بها ( Connetion String )، بالإضافة إلى إعدادات أخرى مثل خيارات التتبع و تسجيل الأخطاء.
في مشاريع .NET الحديثة يتم تمرير هذه الإعدادات عادةً بداخل الملف Program.cs
بأسلوب يقال له Dependency Injection.
3- بعد أن يتم إنشاء الجدول في قاعدة البيانات، يصبح بالإمكان التعامل معه من خلال الإسم الذي أعطي له في الكلاس AppDbContext
، فمثلاً يصبح بإمكاننا التعامل مع الجدول Product
من خلال الإسم Products
كما يلي.
مثال
await _context.Products.ToListAsync(); await _context.Products.FindAsync(1); await _context.Products.AddAsync(product); await _context.SaveChangesAsync();
أي تحديث يتم على Products
لا ينفّذ بشكل مباشر في قاعدة البيانات، بل يُخَزن بشكل مؤقت داخل ككائن DbContext
و يتم إرساله إلى القاعدة عند استدعاء الدالة SaveChanges()
أو SaveChangesAsync()
.