الـ Entity Framework Core أو زي ما بنقول عليه اختصارًا (EF Core)، ده عبارة عن ORM (Object-Relational Mapping). ببساطة كده، هو أداة بتخليك تتعامل مع الـ Database بتاعتك بسهولة جدًا، كأنك بتتعامل مع Classes عادية في الكود بتاعك بدل ما تقعد تكتب SQL بإيدك.


إيه مميزات الـ EF Core؟

الـ EF Core بيقدم شوية مميزات بتسهل الدنيا على المبرمجين:

  • الـ Abstraction: الـ EF Core بيخليك تبص لكل جدول في الـ Database على إنه Model أو Class. يعني إنت بتتعامل مع الـ Database كأنها Collection من الـ Objects وخلاص.
  • الـ Rapid Development: مش هتحتاج تكتب SQL Queries معقدة أو Stored Procedures بنفسك. هتستخدم حاجة اسمها LINQ عشان تعمل الـ CRUD Operations اللي هما (Create, Read, Update, Delete) بسهولة وسرعة.
  • الـ Maintainability: لو عدلت أي حاجة في الـ Models بتاعتك، التعديل ده بيسمّع على طول في شكل الـ Database Schema. الصيانة بتبقى أسهل بكتير.
  • الـ Lazy Loading: الـ EF Core ممكن يجيب الداتا حتة حتة (on-demand) بدل ما يحمل كل حاجة مرة واحدة. ده بيحسن الـ Performance في بعض الحالات (ممكن تقرا أكتر عن استراتيجيات تحميل الداتا زي Lazy Loading vs Eager Loading).
  • الـ Multi-Database Support: الـ EF Core بيدعم أنواع كتير من الـ Databases زي SQL Server، SQLite، MySQL وغيرها.

استراتيجيات الـ Inheritance Mapping

لما يكون عندك Classes بتورث من بعضها (Inheritance Hierarchies), الـ EF Core محتاج يعرف إزاي يمثل الوراثة دي في الـ Database. فيه كذا طريقة أو استراتيجية للموضوع ده (اتكلمنا عن الفرق بينهم كلهم بالتفصيل هنا Inheritance Mapping). الاستراتيجية بتحدد الـ Schema اللي الـ EF Core هيمشي عليه وهو بيحول الكود بتاعك لجداول في الـ Database.

عندك كذا طريقة عشان تحول الـ Inheritance Hierarchies دي للـ Database:

Table Per Hierarchy (TPH)

  • دي الطريقة الافتراضية في الـ EF Core.
  • كل الـ Classes اللي في سلسلة الوراثة بيتخزنوا في جدول واحد (Table) بس.
  • بيكون فيه عمود زيادة اسمه Discriminator column عشان يفرق بين أنواع الـ Objects المختلفة في نفس الجدول.
  • عيبها إن ممكن يبقى عندك قيم NULL كتير في الجدول، وده يعتبر إهدار في مساحة التخزين (Storage).

Table Per Type (TPT)

  • هنا، الـ EF Core بيعمل جدول (Table) منفصل لكل Type أو Class في سلسلة الوراثة.
  • ده ممكن يخلي عمليات الـ CRUD أبطأ شوية أو تعمل Overhead زيادة، عشان هتحتاج تعمل Joins كتير بين الجداول.
  • مشاكل الأداء في الـ TPT:
    • لو جيت تضيف موظف جديد بدوام كامل (Full Time Employee)، هتحتاج تضيف بياناته في جدول الموظفين الأساسي (Employee) وكمان في جدول موظفين الدوام الكامل (Full Time Emp). يعني هتضيف في جدولين.
    • لو جيت تجيب بيانات موظف بدوام جزئي (Part Time emp)، هتحتاج تجيب اسمه وعمره مثلًا من جدول Employee وباقي بياناته من جدول Part Time Emp. ده معناه إنك هتعمل Join بين الجدولين.
    • باختصار، أي عملية CRUD هتحتاج تتعامل مع جدولين، وده مش أحسن حاجة من ناحية التصميم (Design) والأداء (Performance).

Table Per Concrete Class (TPCC)

  • هنا الـ EF Core بيعمل جدول (Table) منفصل لكل Concrete Class بس.
  • الـ Concrete Class هي أي Class ليها تمثيل حقيقي في الـ Business بتاعك (في مثالنا زي Full Time Employee و Part Time Employee، لكن مش الـ Class الأساسية زي Employee لو كانت abstract مثلًا).
  • لازم تتأكد إن نسخة EF Core اللي بتستخدمها بتدعم النوع ده (بقى مدعوم رسميًا في EF Core 7 والإصدارات الأحدث).

ملاحظة مهمة: الطريقة الافتراضية والأكتر استخدامًا هي الـ TPH، وعادةً بتعتبر الأفضل من ناحية البساطة والأداء (Performance) في معظم الحالات.


مقارنة: ADO.NET vs Entity Framework Core vs Dapper

لو محتار تستخدم إيه عشان تتعامل مع الـ Database في مشاريع الـ .NET، تعالى نقارن بين أشهر تلات أدوات: ADO.NET, EF Core, و Dapper.

ممكن تقرا المقال ده لمعلومات أكتر: Dapper vs Entity Framework Core vs ADO.NET: Which One Should You Choose?

1. ADO.NET

(اتكلمنا عنها بالتفصيل هنا ADO DotNet)

  • أول حاجة لازم تعرفها إن ADO.NET مش ORM. بيتقال عليها database access technology أو low-level tool.
  • دي الطريقة “اليدوية” والأساس اللي اتبنت عليه كل أدوات الـ .NET التانية للتعامل مع الـ Database.
  • بتستخدم Classes زي SqlConnection, SqlCommand, SqlDataReader وغيرها عشان تكتب وتنفذ SQL Queries بنفسك.
  • بتديك تحكم كامل في كل تفصيلة، من أول الـ Connections لحد الـ Queries.
  • الأداء (Performance) بتاعها عالي جدًا لأن مفيش أي طبقات وسيطة كتير، بتكلم الـ Database بشكل مباشر.
  • لكن عيبها إن الكود بيكون أكتر بكتير، تفصيلي، وممكن يتكرر، والصيانة ممكن تبقى صعبة في المشاريع الكبيرة.

2. EF Core (Entity Framework Core)

  • ده يعتبر ORM كامل (Object Relational Mapping). بيخليك تحول الـ Database لعالم الـ .NET Classes وتتعامل مع الداتا باستخدام LINQ وكأنها Objects.
  • بيوفر عليك كتابة SQL وتفاصيل ADO.NET الكتير عن طريق الـ abstraction والـ mapping اللي بيعمله بين الـ Models والجداول.
  • It provides a set of classes and APIs that abstract the database operations. (يعني بيقدم مجموعة Classes و APIs بتبسط عمليات الـ Database).
  • EF Core is built on top of ADO.NET, which means it uses ADO.NET internally to interact with databases. (يعني هو مبني فوق ADO.NET وبيستخدمه في الخلفية عشان يكلم الـ Database).
  • مناسب جدًا للتطوير السريع (Rapid Development) والصيانة الأسهل (Maintainability).
  • عيبه إنه ممكن يكون أبطأ شوية من ADO.NET أو Dapper في بعض الحالات بسبب الـ Overhead بتاع الـ abstraction والمميزات الزيادة زي الـ Change tracking.

3. Dapper

(اتكلمنا عنها بالتفصيل هنا Dapper)

  • ده بيتقال عليه Micro ORM. يعني ORM صغير وخفيف.
  • هو عبارة عن طبقة بسيطة فوق ADO.NET، عملها فريق StackOverflow.
  • تصميمه خفيف جدًا وسريع جدًا. بيستخدم Extension Methods على الـ IDbConnection عشان يسهل تنفيذ الـ SQL وتحويل النتائج لـ Objects بسهولة.
  • مش بيقدم كل مميزات الـ ORM الكامل زي EF Core. يعني مش هتلاقي فيه مثلًا change tracking أو Automatic migrations.
  • لكنه بيكون أسرع بكتير من EF Core في العمليات البسيطة والمعاملات الكبيرة لأنه بيقلل التعقيد والـ abstraction.
  • عادةً بيستخدمه المبرمجين اللي محتاجين أداء عالي جدًا (Performance) ومش فارق معاهم يكتبوا SQL بنفسهم، بس عايزين يستفيدوا من سهولة تحويل النتائج لـ Objects.

مقارنة شاملة بين التلاتة

تعالى نبص على مقارنة أوضح بين EF Core, Dapper, و ADO.NET من كذا ناحية:

الأداء (Performance)

  • الـ ADO.NET: زي ما قلنا، دي الطريقة اليدوية. بتكتب SQL وتتعامل مع كل حاجة بنفسك (SqlConnection, SqlCommand). عشان كده الأداء هنا هو الأعلى غالبًا.
  • الـ Dapper: Micro ORM خفيف مبني فوق ADO.NET. أداءه قريب جدًا من ADO.NET لأنه بيعمل بس عملية Mapping بسيطة للـ Objects ومش بيضيف Overhead كتير. يعني سريع جدًا.
  • الـ EF Core: بيقدم مميزات كتير زي LINQ, change tracking, Automatic migrations وغيرها. المميزات دي بتيجي معاها شوية Overhead بيخليه أبطأ نسبيًا مقارنة بـ Dapper و ADO.NET.

سهولة الاستخدام (Ease of Use)

  • الـ EF Core: بيوفر API عالي المستوى (high-level) بيخلي التعامل مع الداتا سهل جدًا عن طريق الـ Classes والـ LINQ بدل كتابة SQL. يعتبر الأسهل في الاستخدام والتطوير السريع.
  • الـ Dapper: سهل نسبيًا، بس لازم تكتب SQL بنفسك. هو بيسهل بس عملية الـ mapping للـ Objects بدون تعقيد.
  • الـ ADO.NET: الأكتر تعقيدًا وتفصيلًا. محتاج تكتب كود كتير وتتعامل مع تفاصيل كتير (low-level) زي إدارة الـ Connection وكتابة الـ Queries.

المزايا والميزات (Features)

  • الـ EF Core: مليان مميزات زي automatic schema migrations و change tracking. لو عايز ORM متكامل ومليان خصائص، EF Core هو الأنسب.
  • الـ Dapper: بيقدم وظايف سريعة وخفيفة للـ object mapping. لكن مفيهوش المميزات التقيلة اللي في EF Core زي الـ change tracking أو automatic migrations.
  • الـ ADO.NET: مفيهوش أي مميزات ORM؛ إنت بتعمل كل حاجة بنفسك. مش هتلاقي LINQ ولا automatic migrations ولا الكلام ده.

المرونة (Flexibility)

  • الـ Dapper: يمكن يكون الأكتر مرونة. بما إنك بتكتب SQL بنفسك، بتقدر تعمل mapping لأي Class أو Structure محتاجها من غير قيود كتير.
  • الـ EF Core: أقل مرونة شوية لأنه بيعتمد بشكل كبير على الـ Models والتخطيط المسبق للجداول وعلاقاتها.
  • الـ ADO.NET: مرن جدًا برضه لأنك بتتحكم في كل حاجة، بس المرونة دي بتيجي على حساب كتابة كود أكتر وتفاصيل أكتر.

الخلاصة: أختار مين فيهم؟

  • الـ ADO.NET: لو أهم حاجة عندك هي أعلى أداء ممكن وتحكم كامل ودقيق (fine-grained control) في كل تفصيلة، ومستعد تكتب كود كتير وتتعامل مع التفاصيل بنفسك.
  • الـ EF Core: لو عايز تطور بسرعة وسهولة، وتستخدم ORM متكامل بمميزات كتير زي LINQ و automatic migrations و change tracking، ومستعد تضحي بشوية أداء مقابل السهولة دي.
  • الـ Dapper: لو الأداء العالي (Performance) مهم جدًا ليك (قريب من ADO.NET)، وفي نفس الوقت عايز مرونة في كتابة الـ SQL واستفادة من سهولة الـ mapping، ومش محتاج كل المميزات التقيلة بتاعة EF Core.

في الآخر، اختيار الأداة الصح بيعتمد على متطلبات مشروعك من ناحية الأداء المطلوب، سرعة التطوير، والمميزات اللي إنت محتاجها.

معلومة إضافية: زي ما قلنا فوق، الطريقة الافتراضية في EF Core لتمثيل الوراثة هي TPH. لو استخدمت TPT، غالبًا هتلاقي نفسك بتعمل Joins أكتر بين الجداول، وده ممكن يأثر على الأداء (Performance) بالسلب.