المتطلبات الأساسية
- الإصدار 10 من .NET SDK. جرى اختبار هذا الدليل باستخدام .NET SDK 10.0.401 وEF Core 10.0.12 و
Npgsql.EntityFrameworkCore.PostgreSQL10.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:
تهيئة الاتصال
انقل شهادة CA التي نزّلتها إلى دليل المشروع، ثم أعد تسميتها إلىca-certificate.pem.
أنشئ قاعدة بيانات للتطبيق. استبدل <PASSWORD> والمضيف بالقيم الظاهرة في النافذة المنبثقة Connect:
appsettings.json ونظام التحكم في الإصدارات:
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:
guide_dotnet يليه public، وانقر على الجدول Todos. يستخدم EF Core أسماء الأصناف والخصائص كمعرّفات بين علامتَي اقتباس، لذا يكون اسم الجدول "Todos" وأسماء الأعمدة "Id" و"Title" وهكذا. يحتوي الجدول على الصف المتبقي:
استخدام PgBouncer
يفتح Npgsql ما يصل إلى 100 اتصال لكل مثيل من التطبيق (Maximum Pool Size). وإذا اقترب مجموع اتصالات المثيلات من الحد الأقصى للاتصالات في Postgres، فاربط التطبيق بدلاً من ذلك عبر PgBouncer المضمَّن. اختر via PgBouncer في نافذة Connect، ثم غيّر المنفذ في سلسلة الاتصال إلى 6432:
- العبارات المُحضَّرة: لا يُحضِّر 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 خاطئة.
الخطوات التالية
- الاتصال: سلاسل الاتصال وPgBouncer وTLS
- الإعدادات: معلمات Postgres وPgBouncer، مثل
max_connections - النسخ المتماثلة للقراءة: توجيه الاستعلامات المخصصة للقراءة فقط إلى نسخة متماثلة
- الأمان: قوائم التحكم في الوصول حسب عناوين IP والشبكات الخاصة