أساسيات DbContext وDbSet
أعدّوا DbContext، وعرّفوا الكيانات، واضبطوا سلسلة الاتصال، وشغّلوا أول استعلام لكم.
أساسيات DbContext وDbSet درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
ما هو Entity Framework Core؟
يُعد EF Core مُطابِق الكائنات بالعلاقات (ORM) الرسمي في .NET. فهو يربط فئات C#، أي الكيانات، بجداول قاعدة البيانات، ويتيح لكم الاستعلام عن البيانات وحفظها باستخدام LINQ، من دون الحاجة إلى SQL في معظم العمليات.
تعريف كيان
الكيان هو فئة C# عادية ترتبط خصائصها بأعمدة قاعدة البيانات. وبحسب الاصطلاح، تصبح الخاصية المسماة Id أو <TypeName>Id مفتاحًا أساسيًا.
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public decimal Price { get; set; }
public int Stock { get; set; }
public DateTime CreatedAt { get; set; }
}إنشاء DbContext
يُعد DbContext البوابة إلى قاعدة البيانات. فهو يحتوي على خصائص DbSet<T> لكل كيان، ويدير الاتصال وتتبع التغييرات والمعاملات.
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Product> Products => Set<Product>();
public DbSet<Order> Orders => Set<Order>();
}تسجيل DbContext باستخدام DI
استدعِ AddDbContext في Program.cs لتسجيل السياق كخدمة Scoped وتهيئة موفّر قاعدة البيانات.
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("Default")));
// For SQLite (great for development/testing):
// options.UseSqlite("Data Source=app.db");الاستعلامات الأساسية باستخدام DbSet
يوفّر DbSet<T> معاملات LINQ. لا تُنفَّذ الاستعلامات حتى يتم تعداد نتائجها (await ...ToListAsync()). ويُسمّى ذلك التنفيذ المؤجّل.
public class ProductService
{
private readonly AppDbContext _db;
public ProductService(AppDbContext db) => _db = db;
public async Task<List<Product>> GetExpensiveAsync(decimal minPrice)
{
return await _db.Products
.Where(p => p.Price >= minPrice)
.OrderBy(p => p.Name)
.ToListAsync();
}
}البحث باستخدام المفتاح الأساسي
يتحقق FindAsync أولًا من ذاكرة التخزين المؤقت المحلية لمتعقّب التغييرات قبل الوصول إلى قاعدة البيانات. استخدمه عند الاستعلام باستخدام المفتاح الأساسي لتجنّب عمليات الذهاب والإياب غير الضرورية.
var product = await _db.Products.FindAsync(42);
if (product is null)
throw new KeyNotFoundException("Product not found");
// For complex keys, pass all key values:
var orderLine = await _db.OrderLines.FindAsync(orderId, productId);إضافة سجلات جديدة
استدعِ Add لوضع كيان في قائمة الانتظار لإدراجه، ثم استدعِ SaveChangesAsync لتثبيت التغييرات. ينشئ EF Core عبارة INSERT بلغة SQL ويملأ Id المُنشأ تلقائيًا.
var product = new Product
{
Name = "Mechanical Keyboard",
Price = 149.99m,
Stock = 50,
CreatedAt = DateTime.UtcNow
};
_db.Products.Add(product);
await _db.SaveChangesAsync();
Console.WriteLine(product.Id); // Auto-generated PKتحديث السجلات
تتتبّع EF Core الكيانات التي تحمّلها. عدّل الخصائص مباشرةً ثم استدعِ SaveChangesAsync — تكتشف EF Core التغييرات وتنشئ عبارة UPDATE محسّنة.
var product = await _db.Products.FindAsync(42);
if (product is not null)
{
product.Price = 129.99m;
product.Stock -= 1;
await _db.SaveChangesAsync(); // UPDATE Products SET Price=...
}حذف السجلات
استدعِ Remove لوضع كيان في حالة الحذف، ثم استدعِ SaveChangesAsync. استخدم ExecuteDeleteAsync (في .NET 7 والإصدارات الأحدث) لحذف السجلات دفعةً واحدةً دون تحميل الكيانات.
// Delete a tracked entity
_db.Products.Remove(product);
await _db.SaveChangesAsync();
// Bulk delete without loading (EF Core 7+)
await _db.Products
.Where(p => p.Stock == 0)
.ExecuteDeleteAsync();التهيئة باستخدام Fluent API
تجاوز OnModelCreating لتهيئة الكيانات باستخدام Fluent API — مثل أسماء الجداول، وأنواع الأعمدة، والقيود، والفهارس، والعلاقات.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>(entity =>
{
entity.ToTable("products");
entity.Property(p => p.Name).IsRequired().HasMaxLength(200);
entity.Property(p => p.Price).HasColumnType("decimal(18,2)");
entity.HasIndex(p => p.Name);
});
}تطبيق عملي: Repository باستخدام DbContext
عادةً ما يغلّف Repository DbContext لتجميع منطق الوصول إلى البيانات في مكان واحد وإبقاء تفاصيل الاستعلامات خارج فئات الخدمة.
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _db;
public ProductRepository(AppDbContext db) => _db = db;
public async Task<Product?> GetByIdAsync(int id)
=> await _db.Products.AsNoTracking().FirstOrDefaultAsync(p => p.Id == id);
public async Task<List<Product>> SearchAsync(string query)
=> await _db.Products
.Where(p => p.Name.Contains(query))
.AsNoTracking()
.ToListAsync();
}اختبار سريع
ماذا تفعل AsNoTracking() عند إجراء استعلام باستخدام EF Core؟
مراجعة: أساسيات DbContext وDbSet
أهم النقاط:
- يمثّل DbContext جلسة الاتصال بقاعدة البيانات، بينما يمثّل DbSet<T> جدولًا
- سجّل DbContext باستخدام
AddDbContextفي DI؛ ويكون نطاقه Scoped افتراضيًا - تُؤجَّل استعلامات LINQ — نفّذها باستخدام
ToListAsyncأوFirstOrDefaultAsync - يتيح تتبّع التغييرات تنفيذ UPDATE وDELETE تلقائيًا عبر SaveChangesAsync
- استخدم
AsNoTracking()للاستعلامات للقراءة فقط لتحسين الأداء
الأسئلة الشائعة
هل درس «أساسيات DbContext وDbSet» مجاني؟
نعم — نص درس «أساسيات DbContext وDbSet» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «أساسيات DbContext وDbSet»؟
أعدّوا DbContext، وعرّفوا الكيانات، واضبطوا سلسلة الاتصال، وشغّلوا أول استعلام لكم. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «أساسيات DbContext وDbSet»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات DbContext وDbSet
- عمليات الترحيل وإدارة المخطط
- عمليات CRUD باستخدام EF Core
- العلاقات: واحد إلى متعدد ومتعدد إلى متعدد