Skip to main content
Entity Framework Core ‏(EF Core) هي أداة ربط الكائنات بقواعد البيانات المعتمدة في منصة ‎.NET، وNpgsql هو مزوّدها الخاص بقاعدة بيانات PostgreSQL. ستُنشئ في هذا الدليل واجهة برمجة تطبيقات مصغّرة (minimal API) باستخدام ASP.NET Core، ثم تُنشئ جدولها عبر عملية ترحيل (migration) في EF Core، وتوفّر نقاط نهاية لعمليات الإنشاء والقراءة والتحديث والحذف. ويعتمد كل اتصال على بروتوكول TLS مع التحقق الكامل من الشهادة.

المتطلبات الأساسية

  • الإصدار 10 من .NET SDK. جرى اختبار هذا الدليل باستخدام .NET SDK 10.0.401 وEF Core 10.0.12 وNpgsql.EntityFrameworkCore.PostgreSQL 10.0.3 (Npgsql 10.0.3).
  • حساب ClickHouse Cloud
  • الأداة psql، لإنشاء قاعدة البيانات. ويمكنك بدلًا من ذلك تنفيذ عبارة CREATE DATABASE في SQL console.

إنشاء خدمة ClickHouse Managed Postgres

في وحدة تحكم ClickHouse Cloud، انقر على New service ثم اختر Postgres. سيكون المثيل جاهزًا خلال بضع دقائق. للاطلاع على شرح تفصيلي للخطوات، راجع دليل البدء السريع.

احصل على بيانات الاتصال

انقر على Connect في الشريط الجانبي الأيسر للخدمة. أبقِ الخيار Directly محددًا، وفعّل Use SSL، ثم انسخ كلمة المرور واسم مضيف الخادم. بعد ذلك انقر على Download CA certificate. ويمكنك أيضًا تنزيل الشهادة لاحقًا من Settings → CA Certificate. هذه الشهادة فريدة لمثيلك، ولذلك يستطيع Npgsql استخدامها للتحقق من أنه يتصل بخادمك فعلًا. يتصل هذا الدليل مباشرةً بـ Postgres عبر المنفذ 5432، سواء للتطبيق أو لعمليات الترحيل في EF Core. فتطبيق ASP.NET Core عملية طويلة الأمد، ويتولى Npgsql أصلًا تجميع الاتصالات داخله (حتى 100 اتصال لكل سلسلة اتصال افتراضيًا)، لذا لا حاجة إلى وسيط تجميع اتصالات إضافي. أما إذا كنت تشغّل مثيلات عديدة من التطبيق، فراجع استخدام PgBouncer. لا تتضمن نافذة Connect المنبثقة علامة تبويب خاصة بـ .NET، كما أن Npgsql لا يقبل عنوان URL بصيغة postgresql:// من علامة التبويب url، بل يستخدم سلاسل اتصال بصيغة Keyword=Value. لذا خذ القيم من عنوان URL وقابلها بالكلمات المفتاحية المناظرة في Npgsql:

إعداد المشروع

أنشئ مشروع ASP.NET Core، وأضف مزوّد Npgsql لـ EF Core وحزمة EF Core الخاصة بوقت التصميم، ثم ثبّت أداة سطر الأوامر dotnet ef:
هل تعمل على تطبيق موجود مسبقًا؟تخطَّ dotnet new web. إذا كان تطبيقك يستخدم EF Core مع SQLite أو مزوّد آخر:
  • شغّل dotnet remove package Microsoft.EntityFrameworkCore.Sqlite وdotnet add package Npgsql.EntityFrameworkCore.PostgreSQL. وثبّت أيضًا Microsoft.EntityFrameworkCore.Design والأداة dotnet-ef إن لم تكونا مثبّتتين لديك.
  • في Program.cs، استبدل UseSqlite بـ UseNpgsql، واحذف سلسلة اتصال SQLite من appsettings.json.
  • عمليات الترحيل (Migrations) خاصة بكل مزوّد، لذا احذف المجلد Migrations. ستُنشئ ترحيلًا أوليًا جديدًا في قسم إنشاء المخطط.
ثم تابع إلى قسم تهيئة الاتصال مستخدمًا اسم سلسلة الاتصال الخاصة بتطبيقك بدلًا من TodoDb، وتخطَّ قسم تعريف النموذج.
فعّل TLS 1.3 على macOSلا تقبل خدمة ClickHouse Managed Postgres سوى TLS 1.3. ولا يدعم .NET على macOS بروتوكول TLS 1.3 افتراضيًا، لذا يفشل كل اتصال بالخطأ Exception while performing SSL handshake مع الخطأ الداخلي bad protocol version. غير أن .NET 10 يمكنه استخدام Network.framework من Apple، وهو يدعم TLS 1.3. أضف ما يلي إلى العنصر <Project> في TodoApi.csproj:
ينطبق هذا الإعداد على التطبيق وعلى dotnet ef، ولا أثر له على Linux أو Windows. ويمكنك بدلًا من ذلك ضبط متغير البيئة DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK=1.

تهيئة الاتصال

انقل شهادة CA التي نزّلتها إلى دليل المشروع، ثم أعد تسميتها إلى ca-certificate.pem. أنشئ قاعدة بيانات للتطبيق. استبدل <PASSWORD> والمضيف بالقيم الظاهرة في النافذة المنبثقة Connect:
خزّن سلسلة الاتصال باستخدام Secret Manager، حتى تبقى كلمة المرور خارج ملف appsettings.json ونظام التحكم في الإصدارات:
يقرأ ASP.NET Core أسرار المستخدم في بيئة Development، وهي البيئة التي يستخدمها dotnet run وdotnet ef افتراضيًا. أما في بيئة الإنتاج، فاضبط متغير البيئة ConnectionStrings__TodoDb بدلًا من ذلك. يُلزم الإعداد SSL Mode=VerifyFull مكتبة Npgsql بالتحقق من أن شهادة الخادم موقّعة من جهة إصدار الشهادات (CA) المحددة في Root Certificate، ومن أنها تطابق اسم المضيف. تحلّ Npgsql المسار النسبي لـ Root Certificate انطلاقًا من دليل العمل الحالي، وهو دليل المشروع عند استخدام dotnet run وdotnet ef. استخدم مسارًا مطلقًا إذا كنت تشغّل التطبيق من موقع آخر.
إذا كانت جهة إصدار الشهادات (CA) خاطئة أو غير موجودة، أو كان المضيف لا يطابق الشهادة (كأن تتصل عبر عنوان IP مثلًا)، يفشل الاتصال بالخطأ Exception while performing SSL handshake مع الخطأ الداخلي The remote certificate was rejected by the provided RemoteCertificateValidationCallback. وإذا لم يكن ملف Root Certificate موجودًا، يظهر الخطأ الداخلي Could not find file. لاحظ أيضًا ما يلي:
  • القيمة الافتراضية في Npgsql هي SSL Mode=Prefer، كما أن SSL Mode=Require لا يتحقق من الشهادة هو الآخر، حتى عند ضبط Root Certificate. لذا اضبط دائمًا SSL Mode=VerifyFull.
  • تقرأ Npgsql متغيري البيئة PGSSLROOTCERT وPGPASSWORD، لكنها لا تقرأ PGHOST ولا PGSSLMODE. ولذلك لا تكفي وحدها المتغيرات الموجودة في علامة التبويب env ضمن نافذة Connect.

تعريف النموذج

أنشئ الملف Todo.cs وأضف إليه صنف الكيان:
Todo.cs
أنشئ الملف TodoDb.cs الذي يتضمن DbContext:
TodoDb.cs
استبدل محتويات Program.cs. يسجّل هذا الملف TodoDb باستخدام مزوّد Npgsql، ويخصّص نقطة نهاية لكل عملية. أما في تطبيق قائم، فيكفيك استدعاء AddDbContext مع UseNpgsql:
Program.cs
تقرأ نقطة النهاية /db/tls العرض pg_stat_ssl الخاص بـ session قاعدة البيانات التابعة للتطبيق نفسه، مما يتيح لك التحقق من أن الاتصال مُشفَّر.

إنشاء المخطط

أنشئ ملف ترحيل (migration) من النموذج ثم طبّقه:
يكتب الأمر dotnet ef migrations add عملية الترحيل في المجلد Migrations، ثم يطبّقها الأمر dotnet ef database update ويسجّلها في الجدول __EFMigrationsHistory. عند التشغيل الأول، يسجّل EF Core استعلام SELECT فاشلًا من __EFMigrationsHistory قبل إنشاء الجدول، ويمكنك تجاهله. قبل تطبيق عمليات الترحيل، يحصل EF Core على قفل كي لا تتمكّن عمليتا نشر من ترحيل قاعدة البيانات نفسها في آنٍ واحد. وعند استخدام Npgsql، يكون القفل عبارة عن LOCK TABLE على __EFMigrationsHistory داخل معاملة الترحيل، لا قفلًا استشاريًا على مستوى session، ولذلك يُحرَّر بمجرد انتهاء المعاملة.

التشغيل والتحقق

شغّل التطبيق على المنفذ 3115:
في طرفية ثانية، أنشئ مهمتين، ثم علِّم الأولى بأنها مُنجزة، واحذف الثانية:
يُعيد طلب DELETE الاستجابة 204 No Content، ولذلك يظهر سطره فارغًا. تحقّق من أن session قاعدة بيانات التطبيق تستخدم TLS:
افتح http://localhost:3115/todos في متصفحك لعرض المهام المتبقية:
لعرض البيانات في وحدة التحكم، افتح SQL console من الشريط الجانبي الأيسر لخدمتك، ثم وسّع guide_dotnet يليه public، وانقر على الجدول Todos. يستخدم EF Core أسماء الأصناف والخصائص كمعرّفات بين علامتَي اقتباس، لذا يكون اسم الجدول "Todos" وأسماء الأعمدة "Id" و"Title" وهكذا. يحتوي الجدول على الصف المتبقي:

استخدام PgBouncer

يفتح Npgsql ما يصل إلى 100 اتصال لكل مثيل من التطبيق (Maximum Pool Size). وإذا اقترب مجموع اتصالات المثيلات من الحد الأقصى للاتصالات في Postgres، فاربط التطبيق بدلاً من ذلك عبر PgBouncer المضمَّن. اختر via PgBouncer في نافذة Connect، ثم غيّر المنفذ في سلسلة الاتصال إلى 6432:
تصلح شهادة CA نفسها هنا أيضًا. يعمل PgBouncer في وضع تجميع المعاملات، لذا قد تُنفَّذ كل معاملة على اتصال Postgres مختلف. ومع الإعدادات الافتراضية لكلٍّ من EF Core وNpgsql، لن تحتاج إلى تغيير أي شيء آخر:
  • العبارات المُحضَّرة: لا يُحضِّر EF Core العبارات، كما أن التحضير التلقائي في Npgsql معطَّل افتراضيًا (Max Auto Prepare=0)، لذا تستخدم الاستعلامات عبارات غير مسمّاة تعمل عبر PgBouncer. أبقِ هذا الإعداد على حاله. فعبر PgBouncer، تفشل العبارات المُحضَّرة الناتجة عن Max Auto Prepare أو NpgsqlCommand.Prepare بشكل متقطع مع الخطأ 08P01: prepared statement did not exist (ويمنع No Reset On Close=true حدوث ذلك)، وبعد أن تُغيِّر عملية ترحيل نوع أحد الأعمدة، يستمر فشلها مع الخطأ cached plan must not change result type، حتى على الاتصالات الجديدة. إذا كنت بحاجة إلى العبارات المُحضَّرة، فاتصل مباشرةً.
  • حالة الجلسة: الإعدادات المضبوطة باستخدام SET، بما فيها search_path، لا تنتقل من معاملة إلى أخرى. استخدم بدلًا من ذلك SET LOCAL داخل المعاملة. يرفض PgBouncer الكلمتين المفتاحيتين Search Path وOptions في سلسلة الاتصال مع الخطأ unsupported startup parameter، في حين تعمل Timezone وApplication Name دون مشكلات.
  • عمليات الترحيل: يعمل الأمر dotnet ef database update أيضًا عبر PgBouncer، لأن قفل الترحيل قفلٌ على مستوى الجدول ينتهي بانتهاء معاملته.
  • التحقق من TLS: يصف pg_stat_ssl الاتصال بين PgBouncer وPostgres، ولذلك يُعيد /db/tls القيمة none. ومع ذلك يظل اتصال تطبيقك بـ PgBouncer خاضعًا للتحقق، إذ يفشل الاتصال بالطريقة نفسها عند استخدام شهادة CA خاطئة.

الخطوات التالية

آخر تعديل في ١٤ أكتوبر ٢٠٢٦