Skip to content

7. دراسة حالة باستخدام Firebird 2.1

7.1. تثبيت الأدوات

الأدوات المطلوب تثبيتها هي كما يلي:

  • نظام إدارة قواعد البيانات (DBMS): [http://www.firebirdsql.org/en/firebird-2-1-5/
  • أداة إدارة: EMS SQL Manager for InterBase/Firebird Freeware [http://www.sqlmanager.net/fr/products/ibfb/manager/download].

في الأمثلة التالية، المستخدم هو sysdba وكلمة المرور هي masterkey.

دعونا نطلق Firebird ثم أداة [SQL Manager Lite for Firebird]، التي سنستخدمها لإدارة نظام إدارة قواعد البيانات.

  • في [1]، نقوم بتشغيل نظام إدارة قواعد البيانات Firebird من قائمة "ابدأ". هنا، لم يتم تثبيت نظام إدارة قواعد البيانات كخدمة Windows؛
  • في [2]، يتم تشغيل الخدمة. يظهر رمز في الزاوية اليمنى السفلية من الشاشة. النقر بزر الماوس الأيمن عليه يسمح لك بإيقاف نظام إدارة قواعد البيانات.

نقوم الآن بتشغيل أداة [SQL Manager Lite for Firebird]، التي سنستخدمها لإدارة نظام إدارة قواعد البيانات [3].

  • في [4]، نقوم بإنشاء قاعدة بيانات جديدة؛
  • في [5]، نؤكد؛
  • في [5]، نقوم بتسجيل الدخول باسم SYSDBA / masterkey؛
  • في [6]، حدد موقع الملف المراد إنشاؤه. سيتم إنشاء قاعدة البيانات كملف واحد؛
  • في [7]، نقوم بالتحقق من صحة عبارة SQL المراد تنفيذها؛
  • في [8]، تم إنشاء قاعدة البيانات. يجب الآن تسجيلها في [EMS Manager]. المعلومات صحيحة. انقر فوق [موافق]؛
  • في [9]، قم بتسجيل الدخول إليها؛
  • في [10]، يعرض [EMS Manager] قاعدة البيانات، وهي فارغة حاليًا.

سنقوم الآن بربط مشروع VS 2012 بهذه قاعدة البيانات.

7.2. إنشاء قاعدة البيانات من الكيانات

نبدأ بنسخ مجلد مشروع [RdvMedecins-SqlServer-01] إلى [RdvMedecins-Firebird-01] [1]:

  • في [2]، في VS 2012، نزيل مشروع [RdvMedecins-SqlServer-01] من الحل؛
  • في [3]، تمت إزالة المشروع؛
  • في [4]، نضيف مشروعًا آخر. هذا المشروع مأخوذ من المجلد [RdvMedecins-Firebird-01] الذي أنشأناه سابقًا؛
  • في [5]، يُسمى المشروع الذي تم تحميله [RdvMedecins-SqlServer-01
  • في [6]، نغير اسمه إلى [RdvMedecins-Firebird-01]
  • في [7]، نضيف مشروعًا آخر إلى الحل. هذا المشروع مأخوذ من مجلد [RdvMedecins-SqlServer-01] الخاص بالمشروع الذي أزلناه سابقًا من الحل؛
  • في [8]، تمت إعادة إضافة مشروع [RdvMedecins-SqlServer-01] إلى الحل.

مشروع [RdvMedecins-Firebird-01] مطابق لمشروع [RdvMedecins-SqlServer-01]. نحتاج إلى إجراء بعض التغييرات. في [App.config]، سنقوم بتعديل سلسلة الاتصال و[DbProviderFactory]، والتي يجب تكييفها مع كل نظام إدارة قواعد البيانات (DBMS).


<!-- connection chain on base -->
  <connectionStrings>
    <add name="monContexte" connectionString="User=SYSDBA;Password=masterkey;Database=D:\data\istia-1213\c#\dvp\Entity Framework\databases\firebird\RDVMEDECINS-EF.GDB;DataSource=localhost;
Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;" providerName="FirebirdSql.Data.FirebirdClient" />
  </connectionStrings>
  <!-- the factory provider -->
  <system.data>
    <DbProviderFactories>
      <add name="Firebird Client Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".Net Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient, Version=2.7.7.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
    </DbProviderFactories>
  </system.data>
  • السطر 3: اسم المستخدم وكلمة المرور، بالإضافة إلى المسار الكامل لقاعدة بيانات Firebird؛
  • الأسطر 8–10: DbProviderFactory. يشير السطر 9 إلى مكتبة DLL [FirebirdSql.Data.FirebirdClient] التي لا نمتلكها. يمكننا الحصول عليها باستخدام NuGet [1]:
  • في [2]، اكتب الكلمة الرئيسية "firebird" في مربع البحث؛
  • في [3]، حدد الحزمة [Firebird ADO.NET Data Provider]. هذا موصل ADO.NET لـ Firebird؛
  • في [4]، المرجع الجديد؛
  • في [5]، في [App.config]، يجب تحديد الإصدار الصحيح لملف DLL. يمكنك العثور عليه في خصائصه.

في ملف [Entities.cs]، تحتاج إلى تكييف مخطط الجداول التي سيتم إنشاؤها:


  [Table("MEDECINS")]
  public class Medecin : Personne
  {...}
 
  [Table("CLIENTS")]
  public class Client : Personne
  {...}
 
  [Table("CRENEAUX")]
  public class Creneau
  {...}
 
  [Table("RVS")]
  public class Rv
  {...}

هنا، لا تحتوي الجداول على مخطط.

نقوم بتكوين تنفيذ المشروع:

  • في [1]، نمنح اسمًا مختلفًا للتجميع الذي سيتم إنشاؤه؛
  • في [2]، نحدد أيضًا مساحة اسم افتراضية مختلفة؛
  • في [3]، نحدد البرنامج المراد تنفيذه.

في هذه المرحلة، لا توجد أخطاء في الترجمة. دعونا نقوم بتشغيل برنامج [CreateDB_01]. نحصل على الاستثناء التالي:

Exception non gérée : System.Data.MetadataException: Le schéma spécifié n'est pas valide. Erreurs :
(11,6) : erreur 0040: Le type rowversion n'est pas qualifié avec un espace de noms ou un alias. Seuls les types primitifs peuvent être utilisés sans qualification.
(23,6) : erreur 0040: Le type rowversion n'est pas qualifié avec un espace de noms ou un alias. Seuls les types primitifs peuvent être utilisés sans qualification.
(33,6) : erreur 0040: Le type rowversion n'est pas qualifié avec un espace de noms ou un alias. Seuls les types primitifs peuvent être utilisés sans qualification.
(43,6) : erreur 0040: Le type rowversion n'est pas qualifié avec un espace de noms ou un alias. Seuls les types primitifs peuvent être utilisés sans qualification.
   à System.Data.Metadata.Edm.StoreItemCollection.Loader.ThrowOnNonWarningErrors
()
   ...
   à RdvMedecins_01.CreateDB_01.Main(String[] args) dans d:\data\istia-1213\c#\d
vp\Entity Framework\RdvMedecins\RdvMedecins-Oracle-01\CreateDB_01.cs:ligne 15

نتذكر أننا واجهنا نفس الخطأ مع MySQL و Oracle و PostgreSQL. ويرتبط هذا بنوع حقل Timestamp في الكيانات. نقوم بإجراء نفس التعديل كما فعلنا مع نظامي إدارة قواعد البيانات السابقين. في الكيانات، نستبدل الأسطر الثلاثة


    [Column("TIMESTAMP")]
    [Timestamp]
    public byte[] Timestamp { get; set; }

مع ما يلي:


    [ConcurrencyCheck]
    [Column("VERSIONING")]
    public int? Versioning { get; set; }

لذلك، نقوم بتغيير نوع العمود من byte[] إلى int?. في نظام إدارة قواعد البيانات (DBMS)، سنستخدم الإجراءات المخزنة لزيادة هذا العدد الصحيح بمقدار واحد في كل مرة يتم فيها إدراج صف أو تعديله.

نجري التغيير المذكور أعلاه على الكيانات الأربعة جميعها ثم نعيد تشغيل التطبيق. ثم نحصل على الخطأ التالي:

1
2
3
4
5
Exception non gérée : FirebirdSql.Data.FirebirdClient.FbException: lock time-out on wait transaction object D:\DATA\ISTIA-1213\C#\DVP\ENTITY FRAMEWORK\DATABASES\FIREBIRD\RDVMEDECINS-EF.GDB is in use ---> FirebirdSql.Data.Common.IscException: lock time-out on wait transaction
object D:\DATA\ISTIA-1213\C#\DVP\ENTITY FRAMEWORK\DATABASES\FIREBIRD\RDVMEDECINS
-EF.GDB is in use
...
   à RdvMedecins_01.CreateDB_01.Main(String[] args) dans d:\data\istia-1213\c#\dvp\Entity Framework\RdvMedecins\RdvMedecins-Firebird-01\CreateDB_01.cs:ligne 15

تشير السطر 1 إلى أن قاعدة البيانات قيد الاستخدام. لا أعتقد أن هذا كان هو الحال، ولم أتمكن من حل هذه المشكلة.

لا بأس. سنقوم بإنشاء قاعدة البيانات [RDVMEDECINS-EF] يدويًا باستخدام أداة [EMS Manager for Firebird]. لن نصف كل خطوة، بل سنكتفي بذكر أهم الخطوات فقط.

ستكون قاعدة بيانات Firebird على النحو التالي:

الجداول

  • في [1]، ID هو مفتاح أساسي له السمة </span>*Autoincrement*. سيتم إنشاؤه تلقائيًا بواسطة نظام إدارة قواعد البيانات؛

تحتوي الجداول المختلفة على نفس المفاتيح الأساسية والخارجية الموجودة في الأمثلة السابقة. وتتمتع المفاتيح الخارجية بالسمة ON DELETE CASCADE.

المولدات

كما هو الحال مع Oracle و PostgreSQL، قمنا بإنشاء مولدات أرقام متسلسلة. يوجد 5 منها [1].

  • سيُستخدم [CLIENTS_ID_GEN] لتوليد المفتاح الأساسي لجدول [CLIENTS
  • سيتم استخدام [MEDECINS_ID_GEN] لتوليد المفتاح الأساسي لجدول [MEDECINS
  • سيتم استخدام [CRENEAUX_ID_GEN] لإنشاء المفتاح الأساسي لجدول [CRENEAUX
  • سيتم استخدام [RVS_ID_GEN] لإنشاء المفتاح الأساسي لجدول [RVS
  • سيتم استخدام [VERSIONS_GEN] لإنشاء القيم لأعمدة [VERSIONING] في جميع الجداول.

المشغلات

المشغل هو إجراء يتم تنفيذه بواسطة نظام إدارة قواعد البيانات (DBMS) قبل أو بعد حدوث حدث (إدراج، تحديث، حذف) في جدول. لدينا 8 مشغلات [1]:

دعونا نلقي نظرة على كود DDL لمشغل [BI_CLIENTS_ID]، الذي يملأ عمود [ID] في جدول [CLIENTS]:

1
2
3
4
5
6
7
8
CREATE TRIGGER BI_CLIENTS_ID FOR CLIENTS
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
      NEW.ID = GEN_ID(CLIENTS_ID_GEN, 1);
END^
  • السطر 2: قبل كل إدراج في جدول [CLIENTS
  • السطران 6-7: إذا كان عمود ID NULL، فقم بتعيين القيمة التالية من مولد الأرقام [CLIENTS_ID_GEN] له.

تم إنشاء المشغلات [BI_CLIENTS_ID، BI_MEDECINS_ID، BI_CRENEAUX_ID، BI_RVS_ID] جميعها بنفس الطريقة.

لنلقِ نظرة الآن على كود DDL لمُشغِّل [CLIENTS_VERSION_TRIGGER]، الذي يملأ عمود [VERSIONING] في جدول [CLIENTS]:

1
2
3
4
5
6
7
CREATE TRIGGER CLIENTS_VERSION_TRIGGER FOR CLIENTS
ACTIVE BEFORE INSERT OR UPDATE
POSITION 1
AS
BEGIN
  NEW."VERSIONING" = GEN_ID(VERSIONS_GEN,1);
END^
  • الأسطر 1–3: قبل كل عملية INSERT أو UPDATE على الجدول [CLIENTS
  • السطر 6: يتلقى العمود ["VERSIONING"] القيمة التالية من مولد الأرقام [VERSIONS_GEN]. يقوم هذا المولد بتعبئة أعمدة ["VERSIONING"] في الجداول الأربعة.

المشغلات [MEDECINS_VERSION_TRIGGER، CRENEAUX_VERSION_TRIGGER، RVS_VERSION_TRIGGER] متشابهة.

تم وضع البرنامج النصي لإنشاء الجداول في قاعدة بيانات Firebird [RDVMEDECINS-EF] في المجلد [RdvMedecins / databases / Firebird]. يمكن للقارئ تحميله وتشغيله لإنشاء الجداول.

بمجرد الانتهاء من ذلك، يمكن تشغيل البرامج المختلفة في المشروع. وهي تعطي نفس النتائج كما هو الحال مع SQL Server، باستثناء برنامج [ModifyDetachedEntities]، الذي يتعطل لنفس السبب الذي تسبب في تعطله مع Oracle و MySQL. يتم حل المشكلة بنفس الطريقة. ما عليك سوى نسخ برنامج [ModifyDetachedEntities] من مشروع [RdvMedecins-Oracle-01] إلى مشروع [RdvMedecins-Firebird-01].

7.3. بنية متعددة الطبقات تستند إلى EF 5

نعود إلى دراسة الحالة الموضحة في الفقرة 2.

سنبدأ ببناء طبقة الوصول إلى البيانات [DAO]. للقيام بذلك، نقوم بنسخ مشروع وحدة التحكم VS 2012 [RdvMedecins-SqlServer-02] إلى [RdvMedecins-Firebird-02] [1]:

  • في [2]، نحذف مشروع [RdvMedecins-SqlServer-02
  • في [3]، نضيف مشروعًا موجودًا إلى الحل. نأخذه من المجلد [RdvMedecins-Firebird-02] الذي تم إنشاؤه للتو؛
  • في [4]، يحمل المشروع الجديد نفس اسم المشروع الذي تم حذفه. سنقوم بتغيير اسمه؛
  • في [5]، قمنا بتغيير اسم المشروع؛
  • في [6]، نقوم بتعديل بعض خصائصه، مثل اسم التجميع هنا؛
  • في [7]، تم حذف مجلد [Models] واستبداله بمجلد [Models] من مشروع [RdvMedecins-Firebird-01]. وذلك لأن كلا المشروعين يشتركان في نفس النماذج.
  • في [8]، المراجع الحالية للمشروع؛
  • في [9]، تمت إضافة موصل Firebird ADO.NET باستخدام أداة NuGet.

في ملف [App.config]، استبدل معلومات قاعدة بيانات SQL Server بمعلومات قاعدة بيانات Firebird. يمكن العثور على هذه المعلومات في ملف [App.config] الخاص بمشروع [RdvMedecins-Firebird-01]:


<!-- connection chain on base -->
  <connectionStrings>
    <add name="monContexte" connectionString="User=SYSDBA;Password=masterkey;Database=D:\data\istia-1213\c#\dvp\Entity Framework\databases\firebird\RDVMEDECINS-EF.GDB;DataSource=localhost;
Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;" providerName="FirebirdSql.Data.FirebirdClient" />
  </connectionStrings>
  <!-- the factory provider -->
  <system.data>
    <DbProviderFactories>
      <add name="Firebird Client Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".Net Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient, Version=2.7.7.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
    </DbProviderFactories>
  </system.data>

تتغير أيضًا الكائنات التي يديرها Spring. لدينا حاليًا:


  <!-- spring configuration -->
  <spring>
    <context>
      <resource uri="config://spring/objects" />
    </context>
    <objects xmlns="http://www.springframework.net">
      <object id="rdvmedecinsDao" type="RdvMedecins.Dao.Dao,RdvMedecins-SqlServer-02" />
    </objects>
</spring>

يشير السطر 7 إلى التجميع الخاص بمشروع [RdvMedecins-SqlServer-02]. أصبح التجميع الآن [RdvMedecins-Firebird-02].

وبعد الانتهاء من ذلك، نكون جاهزين لتشغيل اختبار طبقة [DAO]. أولاً، يجب أن نتأكد من أن قاعدة البيانات مملوءة (باستخدام برنامج [Fill] من مشروع [RdvMedecins-Firebird-01]). ينجح برنامج الاختبار.

نقوم بإنشاء ملف DLL الخاص بالمشروع كما فعلنا مع مشروع [RdvMedecins-SqlServer-02] ونجمع جميع ملفات DLL الخاصة بالمشروع في مجلد [lib] تم إنشاؤه في [RdvMedecins-Firebird-02]. ستكون هذه هي المراجع لمشروع الويب [RdvMedecins-Firebird-03] التالي.

  

نحن الآن جاهزون لإنشاء طبقة [ASP.NET] لتطبيقنا:

سنبدأ بمشروع [RdvMedecins-SqlServer-03]. سنقوم بنسخ مجلد هذا المشروع إلى [RdvMedecins-Firebird-03] [1]:

  • في [2]، باستخدام VS 2012 Express for the Web، نفتح الحل في مجلد [RdvMedecins-Firebird-03
  • في [3]، نقوم بتغيير اسم الحل واسم المشروع؛
  • في [4]، المراجع الحالية للمشروع؛
  • في [5]، نقوم بحذفها؛
  • في [6]، لاستبدالها بمراجع إلى ملفات DLL التي قمنا بتخزينها للتو في مجلد [lib] داخل مشروع [RdvMedecins-Firebird-02].

كل ما تبقى هو تعديل ملف [Web.config]. نستبدل محتواه الحالي بمحتوى ملف [App.config] من مشروع [RdvMedecins-Firebird-02]. بمجرد الانتهاء من ذلك، نقوم بتشغيل مشروع الويب. إنه يعمل. لا تنسَ ملء قاعدة البيانات قبل تشغيل تطبيق الويب.