المتابعون للمدونة

الثلاثاء، 31 أكتوبر 2017

Custom DataSet


إنشاء مجموعات بيانات خاصّة Custom DataSet:
في هذا المقطع سننشئ مجموعات بيانات بدون تحميل أية تفاصيل من قاعدة البيانات.. سننشئها باستخدام مخطط XML، وسنربطها بجدول عرض DataGridView ليستطيع المستخدم إدخال البيانات بها، وسنسمح له بحفظها في ملفّ XML، وإعادة تحميلها بعد ذلك كما يشاء.
ابدأ مشروعا جديدا اسمه CustomDataSet، ومن القائمة الرئيسية Project اضغط الأمر Add New Item لعرض نافذة إضافة عنصر.. من القائمة اليسرى اختر العنصر Data، ومن القائمة اليمنى اختر العنصر DataSet، وحدّد اسما لهذا العنصر الجديد وليكن MyDataSet، واضغط الزرّ OK.
سيضاف مخطّط XML إلى المشروع اسمهMyDataSet.xsd .. انقره مرتين بالفأرة لعرض مصمم المخطط.
لو فتحت صندوق الأدوات الآن، فستجد به أدوات تناسب مخطط XML، وستكون مبوبة تحت الشريط DataSet.. انقر مرّتين بالفأرة على العنصر DataTable لإضافة جدول جديد إلى المخطّط.. هذا الجدول سيظهر في صورة مستطيل فارغ، يحمل الاسم الافتراضيّ DataTable1.. لتغيّر هذا الاسم، اضغطه بالفأرة لإظهار مربع التحرير، واكتب الاسم الجديد Students، ثم اضغط Enter.. كما يمكنك استخدام نافذة الخصائص لتغيير اسم الجدول.
ولإضافة عمود إلى هذا الجدول، اضغطه بزر الفأرة الأيمن، ومن القائمة الموضعية اضغط Add ثم Column.. غير الاسم الافتراضي للعمود الجديد إلى ID.. اضغط F4 لعرض نافذة الخصائص، واستخدم الخاصية DataType لجعله من النوع Int32.. ويمكنك استخدام باقي الخصائص للتحكم في العمود بالطريقة التي تناسبك.. مثلا: اجعل للخاصية AutoIncrement القيمة True لجعل هذا الحقل ترقيما تلقائيا، ولا تنسَ أن تجعل للخاصيتين AutoIncrementSeed و AutoIncrementStep القيمة 1.
اضغط الهامش الأيسر للعمود ID بزر الفأرة الأيمن، ومن القائمة الموضعية اضغط الأمر
Set Primary Key لجعله المفتاح الأساسي.
أضف إلى الجدول عمودا جديدا بنفس الطريقة واجعل اسمه Name.. سيكون نوع هذا العمود String بصور  افتراضية، فاتركه كما هو.. حدد الخاصية Unique في نافذة الخصائص واجعل قيمتها True، ليكون اسم التلميذ متفردا غير قابل للتكرار.. ويمكنك أن تضع في الخاصية MaxLength القيمة 30 لرفض أي اسم أطول من 30 حرفا.
ولو أردت إدراج أي عمود قبل العمود Name، فاضغط هامشه الأيسر بزر الفأرة الأيمن، ومن القائمة الموضعية اضغط الأمر Insert Column.. وتستطيع حذف أي عمود في أي لحظة بتحديده وضغط الزر Delete.
بنفس الطريقة يمكنك إضافة جدول آخر اسمه Subjects، فيه العمودان: ID و Name.. لاحظ أنك تستطيع نسخ الجدول Students باستخدام الأمر Copy ولصق نسخة جديدة منه باستخدام الأمر Paste، حيث سيأخذ الجدول الجديد الاسم Students1، والذي يمكنك تغييره إلى Subjects.. هذا يسهل عليك إنشاء الجداول المتشابهة في تركيبها.
أضف جدولا ثالثا اسمه Grades، وأضف إليه الأعمدة StudentID و SubjectID و Grade، ولا تنس أن تغير نوع بياناتها جميعا إلى Int16.
واضح أننا سنسجل في الجدول Grades درجات كل طالب في كل المواد.. هذه علاقة متعدد بمتعدد Many-to-Many، فالطالب مرتبط بكل المواد، والمادة مرتبطة بكل الطلاب.. هذه فرصة لنجرب التعامل مع هذه العلاقة.
ويجب أن نجعل الحقلين StudentID و SubjectID معا زوجا متفردا، حتى لا نكرر درجة نفس التلميذ في نفس المادة.. لفعل هذا، حدد هذين الحقلين (بضغطهما بزر الفأرة مع ضغط الزر Ctrl من لوحة المفاتيح)، ثم انقرهما بزر الفأرة الأيمن، ومن القائمة الفرعية Add اضغط Key.. ستظهر نافذة إضافة قيد التفرد Unique Constraint، كما في الصورة.
 


في مربع النص العلوي اكتب اسم القيد، وفي القائمة السفلية تأكد أنك اخترت الأعمدة التي سيتم تطبيق القيد عليها (ستجد العمودين StudentID و SubjectID مختارين فعلا لأنك حددتهما قبل فتح النافذة).. ولو أردت جعل هذين العمودين مفتاحا أساسيا للجدول أيضا، فضع علامة الاختيار أمام Primary Key أسفل النافذة.. لكننا لا نحتاج إلى هذا هنا.. اضغط OK لإنشاء قيد التفرد.
نريد الآن أن ننشئ العلاقات بين هذه الجداول.. يمكنك نقر العنصر Relation مرتين بالفأرة في صندوق الأدوات لعرض نافذة إنشاء العلاقة.. أو يمكنك أن تسحب العمود الأساسي من الجدول الرئيسي، وتسقطه على العمود الفرعي في الجدول التابع.. وأنت تسحب أي عمود، لا تمر على عمود آخر في نفس الجدول، وإلا فسيتم تحديده واعتباره جزءا من العلاقة.. لكنك تستطيع تصحيح هذا في نافذة العلاقة على أي حال.. هذه النافذة مألوفة، ولن تجد فيها أي جديد لم نتعرف عليه سابقا.
نريد هنا أن نربط بين العمودين Students.ID و Grades.StudentID، وكذلك بين العمودين Subjects.ID و Grades.SubjectID.. ولا تنس المحافظة على التكامل المرجعي في كل علاقة، باختيار:
Both Relation And Foreign Key Constraint
من القسم: Choose what to create، على أن تجعل اختيارات الحذف والتحديث والرفض Cascade.. هذا سيريحنا من المشاكل التي تحدث عند حذف اسم طالب، أو تغيير اسم مادة، فالتكامل المرجعي سيحافظ على جدول الدرجات صحيحا دائما.
بعد إنجاز هذا، يجب أن يبدو المخطط كالتالي:
 

نريد الآن إنتاج مجموعة بيانات من هذا المخطط.. لفعل هذا انتقل إلى النموذج، وافتح صندوق الأدوات وانقر مرتين على العنصر DataSet.. سيظهر لك مربّع حوار إضافة مجموعة بيانات، وستجد في القائمة العلوية اسم المخطّط MyDataSet.. اضغط OK لإنتاج مجموعة بيانات محددة النوع من هذا المخطط، حيث ستضاف نسخة منها اسمها MyDataSet1 إلى صينية مكونات النموذج.. أقترح تغيير اسمها إلى DsStudents.
من هذه النقطة، يمكنك استخدام مجموعة البيانات بنفس الطريقة التي اعتدتها سابقا، وربطها بجدول العرض، وحفظ وتحميل البيانات بالطريقة المألوفة.. وستجد الكود الكامل الذي يفعل هذا في المشروع CustomDataSet.
لاحظ أن أي تعديل في المخطط XML، ينعكس مباشرة على فئة مجموعة البيانات محددة النوع، لهذا لست في حاجة إلى حذفها ثم إعادة إنشائها، فكل شيء يتم تلقائيا بمنتهى البساطة.
جرب مثلا إضافة عمود محسوب Calculated Column إلى الجدول Grades.. لفعل هذا افتح المخطط، واضغط الجدول Grades بزر الفأرة الأيمن، ومن القائمة الموضعية اضغط الأمر Insert Column.. سمِّ العمود الجديد Subject، وفي نافذة الخصائص حدد الخاصية Expression وضع فيها النص:
Parent(Subjects_Grades).Name
بمجرد أن تفعل هذا ستصير للخاصية ReadOnly القيمة True، وهذا معناه أن المستخدم لا يستطيع تعديل قيم هذا العمود، لأنه سيعرض ناتجا محسوبا بناء على قيمة عمود آخر.. وفي حالتنا هذه، جعلنا هذا العمود يعرض اسم المادة الدراسية، من خلال العلاقة Subjects_Grades التي تربط جدول المواد بجدول الدرجات، حيث سيستخدم العمود Subject قيمة الحقل الفرعي في هذه العلاقة (وهو الحقل SubjectID) ليحضر اسم المادة التي لها نفس الرقم من جدول المواد.. وسنتعرف على الأعمدة المحسوبة بتفصيل أكثر في فصل الجداول.

 

تلاحظ كما هو واضح في الصورة، إن إضافة اسم المادة إلى هذا الجدول سيجعلها تظهر في النافذة التي تعرض درجات الطالب، وهذا أفضل من إرباك المستخدم بعرض رقم المادة، والدرجة التي حصل عليها الطالب فيها.
لاحظ أننا استخدمنا قائمة ListBox لعرض أسماء الطلبة.. هذا يريح المستخدم أثناء إدخاله لدرجات الطلب، بسبب سرعة الانتقال من طالب إلى آخر.
ولعلك تتساءل: لمَ لا يدخل المستخدم أسماء الطلبة ودرجاتهم في نفس النموذج؟
هذا مجرد مثال مختصر، لكن في البرامج الحقيقية، ستحتاج إلى إدخال بيانات الطالب كاملة وليس اسمه فقط، مثل عمره، وفصله الدراسي، وعنوانه، وهاتفه... إلخ.. وكل هذا يحتاج إلى مساحة عرض كبيرة، والأفضل عمل نموذج مستقل له، وهو ما فعلناه في هذا المشروع، ليمكنك البناء عليه فيما بعد.
إلى الآن كل شيء رائع.. لكن تتبقى مشكلة في هذا البرنامج، وهي أن العمود المحسوب Subject سيتم حفظه في الملف عند حفظ مجموعة البيانات، وهو ما سيزيد من حجم الملف بلا ضرورة.. لهذا علينا حذف هذا العمود من مجموعة البيانات قبل حفظها.. لكن هذا سيؤدي إلى حدوث أخطاء في البرنامج!
يمكن حل هذه المشكلة، باستخدام الوسيلة DataSet.Copy لنسخ مجموعة البيانات إلى مجموعة بيانات احتياطية، ثم حذف العمود Subject منها وحفظ بياناتها في الملف.. وبهذا تظل مجموعة البيانات الأصلية كما هي، بينما نحصل على ملف أصغر حجما.. وعند تحميل هذا الملف، لن تحدث أية مشكلة في البرنامج بسبب غياب العمود Subject، فهو عمود محسوب، وسيحسب البرنامج قيمته.. وستجد الكود الذي ينفذ هذا في الزر "حفظ البيانات".
لاحظ أن عيب هذه الطريقة هو أن نسخ مجموعة البيانات بكاملها قد يكون كارثة على الذاكرة إذا كان حجم بياناتها ضخما.. لهذا يمكن اللجوء إلى حل بديل، وهو حذف العمود من مجموعة البيانات قبل حفظها، ثم إنشائه مرة أخرى بعد الحفظ مباشرة.. أسهل طريقة لفعل هذا هي الاحتفاظ بمرجع للعمود في متغير من النوع DataCoulmn قبل حذفه من مجموعة أعمدة الجدول، ثم حفظ البيانات في الملف، ثم إضافة العمود الذي نحتفظ بمرجعه إلى مجموعة الأعمدة مرة أخرى.. وستجد الكود الذي يفعل هذا في الزر "حفظ البيانات 2". 

من كتاب: من الصفر إلى الاحتراف برمجة قواعد البيانات في فيجوال بيزيك دوت نت ADO .NET.. للتنزيل:

 

ليست هناك تعليقات:

إرسال تعليق

ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.

صفحة الشاعر