Entity Framework - استخدام FromSqlInterpolated لكتابة استعلامات خام آمنة

Entity Framework - استخدام FromSqlInterpolated لكتابة استعلامات خام آمنة

أحيانًا أثناء استخدام Entity Framework Core نحتاج إلى كتابة استعلامات SQL مخصصة (Raw SQL Queries) بسبب تعقيد بعض العمليات أو لرغبتنا في أداء أفضل. ولكن كتابة SQL يدويًا قد يعرضنا لخطر حقن SQL (SQL Injection) إذا لم يتم التعامل معه بحذر.

لذلك، توفر EF Core طريقة آمنة لكتابة استعلامات خام باستخدام FromSqlInterpolated لضمان الحماية ضد الحقن.


🔹 ما هو FromSqlInterpolated؟

FromSqlInterpolated هي دالة تتيح لك تمرير استعلام SQL مكتوب يدويًا مع دعم تمرير المتغيرات بشكل آمن، بحيث تتجنب أخطار SQL Injection عبر المعاملات (Parameters).

🔹 الفرق بين FromSqlRaw و FromSqlInterpolated

  • FromSqlRaw: تستخدم استعلام SQL عادي مع معلمات (parameters) يتم تمريرها منفصلة.
  • FromSqlInterpolated: تتيح دمج المتغيرات داخل الاستعلام باستخدام string interpolation مع ضمان حماية تلقائية.

🔹 كيفية استخدام FromSqlInterpolated

مثال عملي: لنفترض أن لدينا جدول منتجات ونريد جلب المنتجات بناءً على سعر معين.


decimal minPrice = 50;

var products = await _context.Products
    .FromSqlInterpolated($"SELECT * FROM Products WHERE Price >= {minPrice}")
    .ToListAsync();

لاحظ كيف استخدمنا $ لدمج المتغير minPrice داخل الاستعلام بشكل آمن. EF Core يتعامل تلقائيًا مع هذا المتغير كـ Parameter وليس نصًا مباشرًا، مما يمنع تمامًا حقن SQL.

🔹 لماذا يعتبر FromSqlInterpolated أكثر أمانًا؟

لأنه يقوم بتحويل المتغيرات إلى معاملات (Parameters) بشكل تلقائي خلف الكواليس، مما يجعل الاستعلام آمناً ضد أي محاولة لحقن أو تلاعب بالاستعلام.

🔹 ملاحظة مهمة عند استخدام FromSqlInterpolated

  • يجب أن يتطابق ناتج الاستعلام مع الكيان (Entity) الذي تستدعي عليه FromSqlInterpolated.
  • إذا كانت الأعمدة المخرجة لا تطابق الكيان تمامًا، قد تحتاج إلى استخدام DTO مخصص أو تعديل الاستعلام.
  • تذكر أن FromSqlInterpolated يسمح فقط بجلب البيانات (SELECT)، ولا يُستخدم مباشرةً لتنفيذ أوامر مثل INSERT أو UPDATE أو DELETE (استخدم ExecuteSqlInterpolated لهذه الأوامر).

🔹 مثال عملي على استخدام متغيرين

لنكتب استعلامًا بجلب المنتجات بسعر بين حدين:


decimal minPrice = 50;
decimal maxPrice = 150;

var products = await _context.Products
    .FromSqlInterpolated($"SELECT * FROM Products WHERE Price BETWEEN {minPrice} AND {maxPrice}")
    .ToListAsync();

🔹 مقارنة بالأكواد العادية (للتوضيح)

مقارنة بين طريقتين (واحدة آمنة باستخدام FromSqlInterpolated والثانية خطيرة باستخدام نص مباشر):


// ❌ طريقة خطيرة (تعرضك لحقن SQL)
var products = await _context.Products
    .FromSqlRaw($"SELECT * FROM Products WHERE Name = '{userInput}'")
    .ToListAsync();

// ✅ الطريقة الآمنة
var productsSafe = await _context.Products
    .FromSqlInterpolated($"SELECT * FROM Products WHERE Name = {userInput}")
    .ToListAsync();

🔹 الخلاصة

استخدام FromSqlInterpolated هو أفضل وأأمن طريقة لكتابة استعلامات SQL مخصصة مع Entity Framework Core. فهو يجمع بين قوة الاستعلامات اليدوية وأمان المعاملات، مما يحميك من هجمات حقن SQL ويجعل الكود نظيفًا ومنظمًا.

تعليقات

المشاركات الشائعة من هذه المدونة

C# - Arrays

Entity Framework - ما هو ORM؟ ونبذة عن Dapper وNHibernate

Entity Framework - مقدمة عن Entity Framework