Skip to content

5. دراسة حالة مع Oracle Database Express Edition 11g الإصدار 2

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

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

  • SGBD: [http://www.oracle.com/technetwork/products/express-edition/downloads/index.html
  • أداة إدارة: EMS SQL Manager for Oracle Freeware [http://www.sqlmanager.net/fr/products/oracle/manager/download
  • عميل Oracle لـ .NET: ODAC 11.2 الإصدار 5 (11.2.0.3.20) مع أدوات Oracle Developer Tools لـ Visual Studio: [http://www.oracle.com/technetwork/developer-tools/visual-studio/downloads/index.html].

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

لنقم بتشغيل Oracle [1] ثم الأداة [SQL Manager Lite for Oracle] التي سنستخدمها لإدارة SGBD [2].

  • في [3]، نقوم بالاتصال بقاعدة بيانات موجودة؛
  • في [4]، نستخدم خدمة Oracle XE للاتصال؛
  • في [5]، نحدد اسم قاعدة البيانات XE؛
  • في [6]، يتم الاتصال باسم system / system؛
  • في [7]، ننهي المساعد؛
  • في [8]، يتم الاتصال بقاعدة البيانات؛
  • في [9]، نكون متصلين؛
  • نظرًا لأننا قمنا بتسجيل الدخول كمستخدم system / system الذي يتمتع بحقوق واسعة، فسيكون بإمكاننا على سبيل المثال إدارة المستخدمين [10]؛
  • في [11]، نقوم بإنشاء مستخدم جديد؛
  • في [12]، سيُسمى [RDVMEDECINS-EF
  • في [13]، وسيكون كلمة المرور rdvmedecins؛
  • في [14]، يتم تأكيد إنشاء المستخدم؛
  • في [15]، تم إنشاء المستخدم؛
  • في [16]، المستخدم [RDVMEDECINS-EF] هو أيضًا مخطط قاعدة بيانات؛
  • في [17]، لا يمتلك المستخدم كما تم إنشاؤه حقوقًا كافية. نمنحه هذه الحقوق عبر برنامج نصي SQL؛
  • في [18]، يتم تنفيذ البرنامج النصي؛
  • في [19]، سنحاول تسجيل الدخول بهوية [RDVMEDECINS-EF] لمعرفة ما يمكنه فعله. للقيام بذلك، نبدأ بتسجيل قاعدة بيانات جديدة في [EMS Manager
  • في [19]، نقوم بتسجيل الدخول عبر الخدمة XE؛
  • في [20]، نقوم بتسجيل الدخول باستخدام الهوية RDVMEDECINS-EF / rdvmedecins؛
  • في [21]، يتم إعطاء اسم مستعار يعكس اسم المستخدم المتصل؛
  • في [22]، يتم تسجيل الدخول إلى Oracle باستخدام المعلومات المقدمة؛
  • في [22]، تم الاتصال بنجاح؛
  • في [23]، نحاول إنشاء جدول في المخطط [RDVMEDECINS-EF
  • في [24]، يتم تعريف جدول عشوائي؛
  • في [25]، يتم التحقق من صحة تعريفها؛
  • في [26]، تم إنشاء الجدول. نقوم بحذفه؛
  • في [27]، تم حذفها.

الآن بعد أن أصبح لدينا مستخدم يتمتع بحقوق كافية، سنقوم بإنشاء المشروع VS 2012 الذي سيقوم بإنشاء جداول المخطط [RDVMEDECINS-EF] استنادًا إلى تعريف الكيانات.

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

نبدأ بنسخ مجلد مشروع [RdvMedecins-SqlServer-01] في [RdvMedecins-Oracle-01] [1]:

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

المشروع [RdvMedecins-Oracle-01] مطابق للمشروع [RdvMedecins-SqlServer-01]. علينا إجراء بعض التعديلات. في [App.config]، سنقوم بتعديل سلسلة الاتصال و [DbProviderFactory] الذي يجب تكييفه مع كل SGBD.


<!-- سلسلة الاتصال بالقاعدة -->
  <connectionStrings>
    <add name="monContexte" connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)));User Id=RDVMEDECINS-EF;Password=rdvmedecins;" providerName="Oracle.DataAccess.Client" />
  </connectionStrings>
  <!-- مزود المصنع -->
  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.DataAccess.Client" />
      <add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </DbProviderFactories>
  </system.data>
  • السطر 3: اسم المستخدم وكلمة المرور؛
  • الأسطر 6-11: DbProviderFactory. تشير السطر 9 إلى DLL [Oracle.DataAccess] التي لا نملكها. يمكن الحصول عليه باستخدام NuGet [1]:
  • في [2]، في منطقة البحث نكتب الكلمة المفتاحية oracle؛
  • في [3]، اختر الحزمة المناسبة [Oracle Data Provider]. إنه موصل ADO.NET من Oracle؛
  • في [4]، المرجع المضاف؛
  • في [5]، في [App.config]، يجب وضع الإصدار الصحيح لـ DLL. يمكن العثور عليه في خصائصه.

في الملف [Entites.cs]، يجب تكييف مخطط الجداول التي سيتم إنشاؤها. المخطط المستخدم هو اسم المستخدم المالك للجداول.


  [Table("MEDECINS", Schema = "RDVMEDECINS-EF")]
  public class Medecin : Personne
  {...}

  [Table("CLIENTS", Schema = "RDVMEDECINS-EF")]
  public class Client : Personne
  {...}

  [Table("RVS", Schema = "RDVMEDECINS-EF")]
  public class Rv
  {...}

  [Table("CRENEAUX", Schema = "RDVMEDECINS-EF")]
  public class Creneau
  {...}

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

  • في [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. ويرتبط ذلك بنوع الحقل Timestamp في الكيانات. نقوم بإجراء التعديل نفسه. في الكيانات، نستبدل الأسطر الثلاثة


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

بالأسطر التالية:


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

لذلك نقوم بتغيير نوع العمود من byte[] إلى int?. نتذكر أنه بالنسبة لكل من SQL Server و MySQL، كان العمود في الجداول الذي يستخدم لإدارة التنافس في الوصول يتلقى قيمة من SGBD في كل مرة يتم فيها إدراج أو تعديل سطر. من الآن فصاعدًا، سنستخدم حقل كيان سيكون عددًا صحيحًا. في SGBD، سنستخدم إجراءات مخزنة لزيادة هذا العدد الصحيح بمقدار وحدة واحدة، في كل مرة يتم فيها إدراج سطر أو تعديله.

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

1
2
3
4
5
6
Exception non gérée : System.Data.DataException: An exception occurred while initializing the database. See the InnerException for details. ---> System.Data.ProviderIncompatibleException: DeleteDatabase n'est pas pris en charge par le fournisseur.
   à System.Data.Common.DbProviderServices.DbDeleteDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
   ...
   à System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   à 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

تشير السطر 1 إلى أن موصل ADO.NET من Oracle غير قادر على حذف القاعدة الموجودة. دعونا نذكر ما يحدث. رمز [CreateDB_01.cs] هو التالي:


using System;
using System.Data.Entity;
using RdvMedecins.Models;

namespace RdvMedecins_01
{
  class CreateDB_01
  {
    static void Main(string[] args)
    {
      // يتم إنشاء قاعدة البيانات
      Database.SetInitializer(new RdvMedecinsInitializer());
      using (var context = new RdvMedecinsContext())
      {
        context.Database.Initialize(false);
      }
    }
  }
}

يُطلق السطر 15 تنفيذ الفئة [RdvMedecinsInitializer] (السطر 12). وفيما يلي نصها:


  public class RdvMedecinsInitializer : DropCreateDatabaseAlways<RdvMedecinsContext>

وهي مشتقة من الفئة [DropCreateDatabaseAlways] التي تحاول حذف قاعدة البيانات ثم إعادة إنشائها. نقوم بتغيير تعريف الفئة إلى:


  public class RdvMedecinsInitializer : CreateDatabaseIfNotExists<RdvMedecinsContext>

لا يتم إنشاء قاعدة البيانات إلا إذا لم تكن موجودة. نعيد تشغيل [CreateDB_01.cs] ولا تظهر أي أخطاء. ولكن في [EMS Manager]، نلاحظ أن قاعدة البيانات [RDVMEDECINS-EF] ظلت فارغة. نظرًا لأن EF 5 عثر على قاعدة بيانات موجودة، فإنه لم يقم بأي شيء. فهو لا يقوم بأي شيء إلا إذا كانت قاعدة البيانات غير موجودة. ومن هنا، ندور في حلقة مفرغة. في الواقع، سلسلة الاتصال بـ SGBD هي كما يلي:


  <connectionStrings>
    <add name="monContexte" connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)));User Id=RDVMEDECINS-EF;Password=rdvmedecins;" providerName="Oracle.DataAccess.Client" />
</connectionStrings>

السطر 2، لا تستخدم سلسلة الاتصال اسم قاعدة بيانات بل اسم مستخدم. يجب أن يكون هذا المستخدم موجودًا.

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

ستكون قاعدة بيانات Oracle كما يلي:

الجداول

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

التسلسلات

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

  • في [2]، نرى خصائص التسلسل [SEQUENCE_CLIENTS]. وهو يولد أرقامًا متتالية بزيادة 1، بدءًا من 1 وحتى قيمة كبيرة جدًا.

جميع التسلسلات مبنية على نفس النموذج.

  • سيتم استخدام [SEQUENCE_CLIENTS] لتوليد المفتاح الأساسي للجدول [CLIENTS
  • سيتم استخدام [SEQUENCE_MEDECINS] لتوليد المفتاح الأساسي للجدول [MEDECINS
  • سيتم استخدام [SEQUENCE_CRENEAUX] لتوليد المفتاح الأساسي للجدول [CRENEAUX
  • سيتم استخدام [SEQUENCE_RVS] لتوليد المفتاح الأساسي للجدول [RVS
  • سيتم استخدام [SEQUENCE_VERSIONS] لتوليد قيم أعمدة [VERSIONING] لجميع الجداول.

المشغلات

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

 

لنلقِ نظرة على كود DDL للمشغل [TRIGGER_PK_CLIENTS] الذي يغذي المفتاح الأساسي للجدول [CLIENTS]:

1
2
3
4
5
6
7
8
CREATE TRIGGER "RDVMEDECINS-EF".TRIGGER_PK_CLIENTS
 BEFORE INSERT
 ON "RDVMEDECINS-EF".CLIENTS
REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW
BEGIN
        SELECT SEQUENCE_CLIENTS.NEXTVAL INTO :new.ID from DUAL;
END;
/
  • الأسطر 1-5: قبل كل عملية INSERT على الجدول [CLIENTS
  • السطر 6: سيأخذ العمود [ID] القيمة التالية من التسلسل [SEQUENCE_CLIENTS]. وبذلك سيكون للمفتاح الأساسي قيم متتالية مقدمة من التسلسل.

المشغلات [TRIGGER_PK_MEDECINS, TRIGGER_PK_CRENEAUX, TRIGGER_PK_RVS] مماثلة.

لنلقِ نظرة على الرمز DDL للمشغل [TRIGGER_VERSIONS_CLIENTS] الذي يغذي العمود [VERSIONING] في الجدول [CLIENTS]:

CREATE TRIGGER "RDVMEDECINS-EF".TRIGGER_VERSION_CLIENTS
 BEFORE INSERT OR UPDATE
 OF
  VERSIONING
 ON "RDVMEDECINS-EF".CLIENTS
REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW
BEGIN
        SELECT SEQUENCE_VERSIONS.NEXTVAL INTO :new.VERSIONING from DUAL;
END;
/
  • السطران 1-2: قبل كل عملية INSERT أو UPDATE على الجدول [CLIENTS
  • السطر 8: سيأخذ العمود [VERSIONING] القيمة التالية من التسلسل [SEQUENCE_VERSIONS]. وبالتالي، سيحتوي العمود [VERSIONING] على قيم متتالية مقدمة من التسلسل.

المشغلات [TRIGGER_VERSION_MEDECINS, TRIGGER_VERSION_CRENEAUX, TRIGGER_VERSION_RVS] مماثلة. تستمد الأعمدة الأربعة [VERSIONING] قيمها من نفس التسلسل.

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

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

1
2
3
4
5
6
7
8
9
1-----------------------------
Client [206,x,x,x,616]
2-----------------------------
Client [206,x,x,y,617]

Exception non gérée : System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Une instruction de mise à jour, d'insertion ou de suppression dans le magasin a affecté un nombre inattendu de lignes (0). Des entités ont peut-être é modifiées ou supprimées depuis leur chargement. Actualisez les entrées ObjectStateManager. ---> System.Data.OptimisticConcurrencyException: أثرت تعليمة التحديث أو الإدراج أو الحذف في المخزن على عدد غير متوقع من الصفوف (0). ربما تم تعديل الكيانات أو حذفها منذ تحميلها. قم بتحديث الإدخالات ObjectStateManager.
   ...
   à RdvMedecins_01.ModifyDetachedEntities.Main(String[] args) dans d:\data\istia-1213\c#\dvp\Entity Framework\RdvMedecins\RdvMedecins-Oracle-01\ModifyDetachedE
ntities.cs:ligne 56
  • الأسطر 1-4: تم تحديث العميل المنفصل بشكل صحيح؛
  • السطر 6: استثناء معروف. وهو الاستثناء الذي نحصل عليه عندما نريد تعديل كيان دون أن يكون لدينا الإصدار الصحيح. لكن هنا، لم نكن نريد تعديل الكيان بل حذفه:

      // حذف كيان خارج السياق
      using (var context = new RdvMedecinsContext())
      {
        // هنا، لدينا سياق جديد فارغ
        // نضع client1 في السياق في حالة محذوفة
        context.Entry(client1).State = EntityState.Deleted;
        // نحفظ السياق
        context.SaveChanges();
}

EF 5 رفض حذف client1 من قاعدة البيانات، لأن client1 (السطر 6) لم يكن له نفس الإصدار. لم نواجه هذه المشكلة مع MySQL. نلاحظ تدريجيًا أن الموصلات ADO.NET لمختلف SGBD تظهر اختلافات طفيفة. نقوم بالتصحيح على النحو التالي:


using (var context = new RdvMedecinsContext())
      {
        // هنا، لدينا سياق جديد فارغ
        // نضع client1 في السياق لحذفه
        context.Clients.Remove(context.Clients.Find(client1.Id));
        // يتم حفظ السياق
        context.SaveChanges();
      }

وقد نجح الأمر.

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

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

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

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

في الملف [App.config]، يتم استبدال معلومات قاعدة بيانات SQL Server بمعلومات قاعدة بيانات Oracle. وتوجد هذه المعلومات في الملف [App.config] التابع للمشروع [RdvMedecins-Oracle-01]:


<!-- سلسلة الاتصال بالقاعدة -->
  <connectionStrings>
    <add name="monContexte" connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)));User Id=RDVMEDECINS-EF;Password=rdvmedecins;" providerName="Oracle.DataAccess.Client" />
  </connectionStrings>
  <!-- مزود المصنع -->
  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.DataAccess.Client" />
      <add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </DbProviderFactories>
  </system.data>

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


  <!-- تكوين Spring -->
  <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-Oracle-02].

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

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

  

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

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

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

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