قواعد المشاركة في المنتدى

(منتدى الأكسس) الموضوع:المساعدة فى عمل شاشة دخول مستخدمين ليكتمل البرنامج بواسطة: (ابراهيم حورس) :: (منتدى الأكسس) الموضوع:طلب مساعده في حليل قاعدة بيانات بواسطة: (kaser906) :: (منتدى الأكسس) الموضوع:كود يظهرسجلات الشهر الحالى بواسطة: (nacer_alger) :: (قسم الاعلانات) الموضوع:ذبايح للبيع بالرياض مع التوصيل0554435958 اغنام للبيع بالرياض بواسطة: (عبدالرحمان) :: (منتدى الأكسس) الموضوع:اظهار البيانات المتشابهه من الجدول الثاني عند الاستعلام بواسطة: (raed99) :: (منتدى الأكسس) الموضوع:اين المشكلة في عملية النسخ الاحياطي بواسطة: (أبو تسنيم) :: (منتدى ADO.NET العام) الموضوع:عمل ابحاث جامعية حصرية بواسطة: (فهد بن ال سعود) :: (منتدى الأكسس) الموضوع:استدعاء مسيرات الرواتب بناء على شرط معين بواسطة: (عمر الرشيدي) :: (قسم الاعلانات) الموضوع:قناة يوتيوب تضم جميع فيديوهات المشاهير بقناة واحدة فقط بواسطة: (mohammedsalha) :: (منتدى ADO.NET العام) الموضوع:حل واجب جامعي باسعار مناسبة بواسطة: (فهد بن ال سعود) :: (قسم الاعلانات) الموضوع:نمتاز بالدقة والمهارة- اعالى الخليج بواسطة: (كوين) :: (قسم الاعلانات) الموضوع:أفضل موقع أخباري عربي ينقل أخبار العالم بواسطة: (اسامة الاحمر) :: (منتدى الكتب الالكترونية) الموضوع:كتاب اهلا بالعالم مسلّي وممتع للمبرمجين المبتدئين والمحترفين بواسطة: (اداء مقنع) :: (أخبار التكنولوجيا) الموضوع:كسب المال من مواقع تصميم التطبيقات بواسطة: (اداء مقنع) :: (قسم الاعلانات) الموضوع:شقق للبيع ش الخمسين النزهه 2 برنى 150 م بواسطة: (جمعة عللاممن) :: (منتدى Microsoft Excel) الموضوع:معادلة في الاسهم بواسطة: (awad1) :: (قسم الاعلانات) الموضوع:ماكينة التشكيل الحراري للبلاستيك فاكيوم بواسطة: (asma79) :: (قسم الاعلانات) الموضوع:خط انتاج الفحم المضغوط تصنيع الشركة العصرية للصناعات الهندسية بواسطة: (asma79) :: (قسم الاعلانات) الموضوع:اسعار الدريسنج رووم بواسطة: (هند صبرى 100) :: (قسم الاعلانات) الموضوع:أحدث أجهزة الحضور والانصراف ماركة ID WATCHER بواسطة: (eng sara)


راديو القرآن

المواضيع المثبته: (منتدى برمجة التقارير) الموضوع:مثال Crystal Report بواسطة: (شهرزاد) :: (منتدى مبرمجي Microsoft Visual VB.NET) الموضوع:طريقة تخزين أي نوع ملفات في Access DataBase ومشاهدتها وتشغيلها بواسطة: (jbsa) :: (منتدى مبرمجي ASP) الموضوع:كتاب مكون من 16 جزاء يتكلم عن asp بواسطة: (amricost) :: (منتدى مبرمجي Microsoft Visual C#.NET) الموضوع:Serial Communication with Csharp بواسطة: (Prof.Mendl) :: (القسم المفتوح) الموضوع:الأعمــــال الصالحة المستمــرة للإنســـان بعد وفاته بواسطة: (عبدالله جابر شقليه) :: (منتدى مبرمجي Microsoft Visual VB.NET) الموضوع:دورة تحزيم البرامج Setup & Deployment Applications by VS 2008 بواسطة: (Max Bayne) :: (منتدى Microsoft Visual Basic) الموضوع:الدليل الأسرع لأبرز المواضيع بواسطة: (HnHn) :: (منتدى مبرمجي Microsoft Visual C#.NET) الموضوع:مكتبة الأمثلة والتطبيقات للغة #C بواسطة: (النور) :: (منتدى ADO.NET العام) الموضوع:البدء مع ADO.NET بواسطة: (HnHn) :: (لغة PHP) الموضوع:دوره بي اتش بي بالفيديو php video tutorial بواسطة: (blackmanblack) :: (منتدى ADO.NET العام) الموضوع:الكامل في قواعد البيانات مع VB.net بواسطة: (المهندس عدي) :: (منتدى أنظمة الشبكات وأمنها) الموضوع:الشبكات الحاسوبية ..Computer Network.. بواسطة: (مرحبا الساع) :: (Oracle قسم قواعد البيانات أوراكل) الموضوع:جمل استعلام بواسطة: (وليد القدسي) :: (منتدى مبرمجي ASP) الموضوع:مشروع تخرج القرية الذكية المصرية بواسطة: (caco) :: (منتدى مبرمجي لغة جافا JAVA) الموضوع:برنامج للموبايل بلغة الجافا للبحث على جوجل بواسطة: (Doctors) :: (منتدى مبرمجي Microsoft Visual VB.NET) الموضوع:حصرياً : كل شيء يخص الفيجوال بيسك دوت نت - اسطوانات - كتب - أكواد - ال بواسطة: (صائبكو) :: (منتدى الكتب الالكترونية) الموضوع:كتاب كامل من جزئين يشرح access وبالتفصيل وقواعد البيانات وبالتفصيل بواسطة: (m.i.a.r) :: (منتدى Microsoft Excel) الموضوع:شرح دوال الاكسيل كلِ على حده بواسطة: (ramies) :: (قسم الدروس و الدورات) الموضوع:برمجة بصمة الاصبع مع الدوت نت Microsoft FingerPrint Reader بواسطة: (FunctionSys) :: (منتدى برمجة الجرافكس) الموضوع:كلمه بخصوص قسم الجرافيك الجديد بواسطة: (alaa gomaa)

عدد الصفحات : 2  1  2   > » موضوع مغلق إضافة موضوع جديد

> ربط قاعدة البيانات والفرق بين الوضع المتصل والوضع المنفصل وشرحها بالتفصيل,دورة بربط قاعدة البيانات مع vb2005 و vb 2008 وشرحها بالتفصيل
Bookmark and Share
تقييم الموضوع Label معدل التقيم:0
مشاركةالخميس,10/ربيع الثاني/1431 هـ,02:29 مساءً
المشاركة #1

الرتبة في المنتدى:رقيب

أيقونة المجموعة

المجموعة: الأعضاء
المشاركات: 36
سجل في:الأربعاء,21/جمادى الأولى/1428 هـ,10:17 صباحاً
الدولة:السعودية
رقم العضوية: 27628



بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
نعلم جميعا ان ما يميز الوضع المنفصل عن المتصل هو في حالة الوضع المنفصل يتم قطع الاتصال بقاعدة البيانات ويتم التعامل مع الداتاسيت ...الخ ولكن لي استفسار بسيط وهو في الوضع المتصل لو قمت بعمل قطع الاتصال بقاعدة البيانات باستخدام con.close وذلك بعد كل عملية ادخال او حذف او تعديل او عند استخدام Datareader إذن ما هو الفرق طالما انا قمت بعمل قطع الاتصال اذا كان Dataadapter تقوم بقطع الاتصال بقاعدة البيانات تلقائي في حالة الوضع المنفصل فأنا كمبرمج اقوم بقطع الاتصال في حالة الوضع المتصل كما ذكرت اعلاه إذن ما هو الفرق ثاني استفسار نجد انه في حالة برامج مثل برامج الحجز في شركات الطيران مثلا نجد انهم يستخدمون الوضع المتصل ونجد ان عدد كبير جدا من المستخدمين يستخدمون نفس البرنامج في وقت واحد دون اي مشاكل اذن ما هو الذي يميز الوضع المنفصل عن الوضع المتصل مع الشكر للجميع


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالخميس,10/ربيع الثاني/1431 هـ,02:58 مساءً
المشاركة #2

خبيرتحليل نظم و دوت نت
الرتبة في المنتدى:عماد

أيقونة المجموعة

المجموعة: مشرفي الموقع
المشاركات: 3849
سجل في:الأحد,17/محرم/1428 هـ,05:57 صباحاً
الدولة:الأردن
رقم العضوية: 19244






اخي الكريم

في الوضع المتصل انت تتعامل مع قاعدة البيانات بشكل مباشر ، فاذا حدث اي خلل في البرنامج او الجهاز فان قاعدة البيانات من الممكن

ان تتأثر فلذلك نقوم بقطع الاتصال بعد كل عملية.

اما الوضع المنفصل فان البيانات تخزن بالذاكرة لذلك يكون التعامل معها من حيث الفرز والاستفسار والتقارير اسرع .

وانه بعد كل عملية ادخال او حذف او تعديل تعكس هذه المعلومات في ذاكرة الجهاز وليس بقاعدة البيانات الا اذا تم تنفيذ امر
update,ACCEPTCHANGES عندها فقط يتم تخزينه بقاعدة البيانات.


تحياتي للجميع
ابو سامر
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالأربعاء,06/جمادى الثانية/1431 هـ,06:17 مساءً
المشاركة #3

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519




* الاتصال المنفصل ( Connectionless Oriented ) :

يعد الوضع المنفصل هو الأمثل للتعامل مع قواعد البيانات ، وذلك نظراً للإمكانات والكائنات المتنوعة التي تمكن المستخدم من أخذ نسخة من الجداول المخزنة في قاعدة البيانات ، وقراءة البيانات المخزنة فيها ، وتعديلها و عرضها وتصفيتها ومعالجتها أو إنشاء علاقات فيما بينها ، وذلك لفترات طويلة ، دون أن تستهلك الكثير من موارد النظام ، ويترتب على ذلك عمل التطبيقات بكفاءة عاليه . ولأن معظم مصادر البيانات تدعم عدداً محدوداً من الاتصالات المفتوحة ، فإن الوضع المنفصل استطاع أن يتجاوز هذه المشكلة ، لاسيّما حين نستخدم تطبيقات متصلة بقواعد البيانات عبر شبكة الإنترنت ...
وتتلخص فكرته في أن نقوم بإجراء اتصال بقاعدة البيانات ، وذلك بواسطة كائن الاتصال Connection وبعد قبول الاتصال نقوم بأخذ نسخة من البيانات المخزنة في مصدر البيانات "Data Sources" ( مصدر البيانات هنا هو ملف قاعدة البيانات بالنسبة لـ Microsoft Office Access أو السيرفر بالنسبة لـ SQL Server ) ، ثم نقوم بتخزينها في الذاكرة ، وذلك من خلال كائن يكون بمثابة مستودع للبيانات ويسمى DataSet ( مجموعة البيانات ) ، ولكي تتم هذه العملية يحتاج هذا الكائن إلى كائن أخر يسمى DataAdapter ( موفّق البيانات ) يكون بمثابة وسيط بين مجموعة البيانات "DataSet " ومصادر البيانات "Data Sources" ، حيث يقوم DataAdapter بعملية فتح الاتصال بقاعدة البيانات و استيراد وتصدير البيانات من و إلى مصدرها الأساسي ، وبعد تخزين البيانات في DataSet ، فإنها تصبح منفصلة عن مصدر البيانات ، لان الكائن DataAdapter يقوم بشكل تلقائي أيضاً بقطع الاتصال بقاعدة البيانات ، وهذا الانفصال والاستقلال هو السبب في تسمية هذه الطريقة بالاتصال المنفصل أو الوضع المنفصل ، وهو السر في تفوقه على الوضع المتصل ، لأنه يتغلب على جمع عيوبه ومشاكله .
ومن ذلك نستطيع أن نقول أن الكائنات الأساسية في الوضع المنفصل هي : Connection ، DataSet ، DataAdapter .
وهناك أيضاً كائنات أخرى ليست فرعية ولكنها خدمية إن صح التعبير ،على سبيل المثال " DataTable ، DataRow ، DataColumn ، DataRelation ، OleDbCommandBuilder ، BindingManagerBase ، CurrencyManager ، BindingSource " ،
ويأتي دورها في الغالب بعد وصول البيانات ( الجداول ) القادمة من مصادر البيانات إلى DataSet ( مجموعة البيانات ) . وسنُناقش بعضها ( أو كلها إذا وجدنا الوقت الكافي لذلك ) وما يهمنا منها بإيجاز غير مخل إن شاء الله ..
ملاحظة : لسنا مجبرين على استخدام كل الأدوات والخصائص التي سوف ترد في الشرح ، ولكن ما يلزمنا منها فقط ، وسوف تتضح لنا الكثير من الأمور حين نصل إلى الجزء العملي من الدرس .
- - - - - - - - - - - - - - - - - - - - - - -
وألان سون نتطرق لبعض خصائص DataSet :
* الخاصية Clear :
تزيل هذه الخاصية كل البيانات من جميع جداول DataSet ، بينما تبقي تعريفات الجداول وأي تقييدات معرفه من قبل DataSet ...
MyDs.Clear

فإذا أردنا إزالة الجداول والتقييدات ، نقوم بإعادة إنشاء DataSet كما في الكود التالي ..
MyDs = New DataSet

الخاصية HasChanges :
إن DataSet يتتبع فيما إذا كان هناك أي تغييرات قد أجريت على بياناته ، ويمكن استدعاؤها بكل بساطه من خلال الكود التالي ..
MyDs.HasChanges

وتعيد هذه الخاصية القيمة true إذا كانت البيانات قد حدثت إما لتغيير أو إضافة أو حذف ، فإذا حمل برنامج ما بشكل أولي بيانات إلى DataSet ، فإن البيانات لم تغيّر بعد وستعيد هذه الخاصية عندئذ القيمة False وعندما يُحَدِّث المستخدم أي بيانات للجداول فإن هذه الخاصية سوف تعيد القيمة true . وإذا قام المستخدم بحفظ بياناته المحدثة ، فإنها تعيد القيمة False من جديد ..
فلنتأمل هذا الكود ..
If MyDataSet.HasChanges(DataRowState.Added) Then
          ' نقوم بكتابة أي إجراء في حالة إذا كان هناك صفوف جديدة قد أضيفت. 
ElseIf MyDataSet.HasChanges(DataRowState.deleted) Then
          ' نقوم بكتابة أي إجراء في حالة إذا كان هناك صفوف قد حذفت . 
ElseIf MyDataSet.HasChanges(DataRowState.Modified) Then
          ' نقوم بكتابة أي إجراء في حالة إذا كان هناك صفوف قد تغيرت قيمها 
ElseIf MyDataSet.HasChanges(DataRowState.Unchanged) Then
          ' نقوم بكتابة أي إجراء في حالة إذا لم يحدث أي تغيير على الصفوف .
End If

ويمكن أن تأخذ هذه الخاصية وسيط اختياري يسمى DataRowState ، يشير إلى نوع التغييرات التي قد حدثت ، حيث يمكن استخدام هذه الطريقة لرؤية فيما إذا كانت هناك سجلات قد أضيفت ، أو عدلت ، أو حذفت ، أو لم يقع عليها أي تغيير ، وذلك من خلال القيم التي يحملها هذا الوسيط وهي على النحو التالي ..
- Added : ويشير إلى الصفوف التي أضيفت إلى الـ DataSet .
- deleted : ويشير إلى الصفوف التي قد حذفت من الـ DataSet .
- Modified : ويشير إلى الصفوف التي قد غيرت قيم بياناتها من الـ DataSet .
- Unchanged : ويشير إلى أن الصفوف لم تتغير من الـ DataSet .
الخاصية AcceptChanges :
تقوم هذه الخاصية بإعادة وضع الـ DataSet الذي تم التعديل لبياناته ، ليشير إلى أن البيانات لم تعدل . جاعلاً الاستدعاءات المستقبلية للخاصية HasChanges تعيد القيمة False . إنه من الهام جداً إدراك أن AcceptChanges لا تقوم بالواقع بتحديث قاعدة البيانات ، إنها فقط تعيد وضع الـ DataSet المعدل . وبشكل نموذجي فإن أي برنامج سيقوم بتخزين أية تغييرات إلى قاعدة البيانات ، ومن ثم يستدعي AcceptChanges بعد ذلك مباشرة .
' كود تصدير البيانات المحدثة من مجموعة البيانات إلى مصدر البيانات باستخدام موفّق البيانات
MyDs.AcceptChanges

الخاصية RejectChanges :
تقوم هذه الخاصية بإلغاء أية تغييرات قد أجريت على البيانات في الـ DataSet منذ تحميلها ، أو منذ أخر استدعاء لها ، بمعنى أنها تلغي أية أسطر مضافة حديثاً ، وتستعيد أسطراً حذفت أيضاً حديثاً ، وتعيد وضع الأسطر المعدلة إلى قيمتها السابقة ، كما أنها تقوم بإعادة وضع الـ DataSet الذي تم التعديل لبياناته ، ليشير إلى أن البيانات لم تعدل . جاعلاً الاستدعاءات المستقبلية للخاصية HasChanges تعيد القيمة False .
MyDs.RejectChanges

ملاحظة :
تقوم الخاصية AcceptChanges بإزالة المعلومات حول الحالة السابقة للبيانات ، وبالتالي لا يمكن استخدام RejectChanges لاستعادة آخر قيم للبيانات ، هذا يعني أن RejectChanges سيؤدي إلى استعادة البيانات بالحالة التي كانت عليها بعد آخر استدعاء للخاصية AcceptChanges .
الخاصية GetChanges :
تساعدنا هذه الخاصية في إنشاء كائن DataSet جديد بنفس بنية الكائن الأصلي ، ولكنه يحتوي فقط على سجلات تمثل التغييرات التي حدثت للبيانات ، وله أيضاً وسيط إختياري DataRowState ( الذي تحدثنا عنه في الخاصية HasChanges ) يخبر GetChanges فيما إذا يتوجب عليها إحضار السجلات التي أضيفت أو عدلت أو حذفت أو تركت دون تغيير . وبالإمكان جمع قيم DataRowState لاختيار أكثر من نوع واحد من التغييرات التي حدثت للبيانات داخل الكائن DataSet .
ولها استخدامات كثيرة منها :
1- قلنا سابقاً ، نحن في الوضع المنفصل نستخدم الكائن DataAdapter لإعادة تخزين التغييرات الموجودة في DataSet إلى مصدر قاعدة البيانات . وذلك يتم من خلال الخاصية update التابعة للكائن DataAdapter الذي سوف نتحدث عنه فيما بعد ، ما يهمنا هنا هو أن هذه الخاصية تبحث خلال DataSet عن تغييرات وتخزنها واحداً تلو الآخر . ويكون تخزين التغييرات أسرع إذا جُمعت في مجموعات حسب نوعها ، وبكلمات أخرى فإن الخاصية update ستعطي إنجازاً أفضل ، إذا حفظت كل التعديلات أولاً ، ثم بعد ذلك كل الإضافات وأخيراً كل المحذوفات .
2- أحياناً يحتاج برنامج ما تخزين تغييرات في ترتيب معين ، ليفي بمتطلبات التقييدات العلائقية لجداول قاعدة البيانات .
ولكي نفهم طريقة هذه الخاصية ، فلنتابع سوياً هذه الأمثلة ..
مثال 1 : ( إخبار المستخدم عن عدد السجلات الجديدة )
في هذا المثال نقوم بالتصريح عن كائن DataSet جديد ، ثم نختبر فيما إذا كان الكائن الأصلي يحتوي على أي تغييرات عليه ، وفي حالة وجود أي تغيير نستخدم الخاصية GetChanges لتأهيل الكائن الجديد بنفس بنية الكائن الأصلي ، ويحتوي فقط على السجلات التي أضيفت ، وقبل أن نخبر المستخدم عن عدد السجلات الجديدة نختبر الكائن الجديد لنتأكد من احتوائه على بيانات ، وفي حالة وجود بيانات نخبر المستخدم بذلك ..
   Dim ds_added As New DataSet
   If MyDS.HasChanges Then
           ds_added = MyDS.GetChanges(DataRowState.Added)
           If (Not (ds_added) Is Nothing) Then
                   MsgBox(ds_added.Tables(0).Rows.Count & " Records Added ")
           End If
End If

ويمكن قياس هذا المثال على باقي القيم (deleted ، Modified ، Unchanged )
مثال 2 : (جمع قيم DataRowState لاختيار أكثر من نوع واحد من التغييرات التي حدثت للبيانات داخل الكائن DataSet )
في هذا المثال نقوم بالتصريح عن كائن DataSet جديد ، ثم نختبر فيما إذا كان الكائن الأصلي يحتوي على أي تغييرات عليه ، وفي حالة وجود أي تغيير نستخدم الخاصية GetChanges لتأهيل الكائن الجديد بنفس بنية الكائن الأصلي ، ويحتوي فقط على السجلات التي أضيفت أو حذفت ، وقبل أن نخبر المستخدم عن عدد السجلات الجديدة أو المحذوفة ، نختبر الكائن الجديد لنتأكد من احتوائه على بيانات ، وفي حالة وجود بيانات نخبر المستخدم بذلك ..
   Dim ds_AddedOrdeleted As New DataSet
   If MyDS.HasChanges Then
           ds_AddedOrdeleted = MyDS.GetChanges(DataRowState.Added Or DataRowState.deleted)
           If (Not (ds_AddedOrdeleted) Is Nothing) Then
                   MsgBox(ds_AddedOrdeleted.Tables(0).Rows.Count & " Records Added or deleted ")
           End If
End If

مثال 3 : ( تحديث التغييرات حسب نوعها ، لتخزين البيانات بشكل أسرع )
ملاحظة : نرجو التركيز على الجزء الخاص بـ GetChanges حتى تتضح الصورة الكاملة في أذهاننا من خلا متابعة باقي الدروس ، بعدها يمكننا فهم باقي تفاصيل الكود الغامضة في هذا الوقت .
في هذا المثال نقوم بالتصريح عن كائنين DataSet جديدين ، وكائن أخر يسمى باني الأوامر CommandBuilder
ملاحظة : الكائن CommandBuilder يقوم ببناء الأوامر الخاصة بتحديث البيانات من تعديل وإضافة وحذف ، والتي يحتاجها الكائن DataAdapter في عملية التحديث .
وخلال ذلك التصريح نقوم بربط كائن CommandBuilder بـالكائن DataAdapter ، ثم نقوم بإيقاف التحديث للبيانات الموجودة في الـ DataSet وقبول التحديثات الحالية من أجل حفظها ونقلها من الـ DataSet إلى مصدر البيانات ، ثم نختبر فيما إذا كان الكائن Dataset الأصلي يحتوي على أي تغييرات عليه ، وفي حالة وجود أي تغيير نستخدم الخاصية GetChanges لتأهيل الكائن الجديد ds_Changes بنفس بنية الكائن الأصلي ، و نستخدم أيضاً الخاصية GetChanges لتأهيل الكائن الجديد ds_subset بنفس بنية الكائن ds_Changes ، وجعله يحتوي فقط على السجلات التي عدلت ، وقبل حفظ البيانات ونقلها من الـ DataSet إلى مصدر البيانات باستخدام الخاصية update التابعة للكائن MyDataAdapter ، نختبر الكائن الجديد ds_subset لنتأكد من احتوائه على بيانات ، وفي حالة وجود بيانات نقوم بعملية النقل . ثم نكرر الجزء الأخير من الشرح بالنسبة لكل من الإضافة والحذف ، وفي الأخير نستدعي الخاصية AcceptChanges لإعادة وضع الـ DataSet الذي تم التعديل لبياناته ، جاعلاً الاستدعاءات المستقبلية للخاصية HasChanges تعيد القيمة False..
   Dim ds_Changes As New DataSet
   Dim ds_subset As New DataSet
   Dim MyCB As New OleDbCommandBuilder(MyDataAdapter)
   Me.BindingContext(MyDS, "Information").EndCurrentEdit()
   If MyDS.HasChanges Then
          ds_Changes = MyDS.GetChanges
          ds_subset = ds_Changes.GetChanges(DataRowState.Modified)
          If (Not (ds_subset) Is Nothing) Then MyDataAdapter.update(ds_subset.Tables(0))
          ds_subset = ds_Changes.GetChanges(DataRowState.Added)
          If (Not (ds_subset) Is Nothing) Then MyDataAdapter.update(ds_subset.Tables(0))
          ds_subset = ds_Changes.GetChanges(DataRowState.deleted)
          If (Not (ds_subset) Is Nothing) Then MyDataAdapter.update(ds_subset.Tables(0))
          MyDS.AcceptChanges()
End If

الخاصية HasErrors :
نفرض أن مستخدماً أدخل القيمة " ADO " في حقل من النوع Integer عندئذ يمكن للبرنامج أن يُعلِّم هذا الحقل في هذا السجل بالذات برسالة خطأ . لاحقاً وقبل أن يقوم البرنامج بتحديث قاعدة البيانات ، فإنه يمكن استخدام خاصية HasErrors الخاصة بـ DataSet لتحديد فيما إذا كانت البيانات تملك أخطاء يتوجب على المستخدم إصلاحها .
ربما يرى البعض أنه من الأفضل أن يخبر البرنامج المستخدم عن وجود أخطاء في البيانات المدخلة مباشرة ، مثل استخدام الأداة ErrorProvider ، ولكن أحياناً يكون من المفيد تأجيل معالجة الأخطاء . كمثال : ربما كانت قيمة أحد الحقول تعتمد على قيمة حقل آخر لم تدخل بعد ، في هذه الحالة فإن البرنامج يجب عليه الانتظار حتى تدخل كلا القيمتين ، قبل أن يقرر فيما إذا كانت هناك مشكلة ما .
وتعيد هذه الخاصية القيمة true إذا كانت البيانات تملك أخطاء يتوجب على المستخدم إصلاحها ، وبالمقابل القيمة False إذا لم توجد أخطاء في البيانات .
مثال :
If MyDataSet.HasErrors = True Then
   ' أدخل الكود الخاص بتصحيح الخطأ
Else
   ' أدخل الكود الخاص بحفظ البيانات المدخلة
End If

الخاصية Tables :
نصل من خلال هذه الخاصية إلى الجداول المخزنة في DataSet ومنها إلى الصفوف والأعمدة الموجودة في هذه الجداول ، بل و إلى القيم المخزنة في أي خلية من الخلايا الموجودة في الجدول .
ويتم تحديد اسم الجدول الذي نريد أن نتعامل معه بواسطة هذه الخاصية بطريقتين ، أولاهما هي أن نكتب اسم الجدول ( وهي الأفضل للمزيد من الوضوح ) كما في المثال التالي ..
MyDS.Tables("Information")

والطريقة الثانية هي أن نرمز للجدول من خلال رقمه داخل الكائن DataSet علماً أن رقم أول جدول داخل الكائن DataSet هو الرقم 0 ، كما في المثال التالي ..
MyDS.Tables(0)

ويمكن أيضاً التحكم في صفوف الجدول المحدد من خلال الخاصية Rows التابعة له ، والخاصية Item التابعة لها ، وكل ذلك يتم بشكل مباشر بدون كائنات خدمية .
وسوف أقوم بطرح مجموعة من الأمثلة ، لعلها تعين على الاستيعاب بشكل أفضل ..
ملاحظة : ما سوف يتم شرحه في السطور التالية من باب العلم بالشيء ، وإلا فإن الكائنات الخدمية (BindingManagerBase أو CurrencyManager أو BindingSource ) تغنينا عن ذلك وبشكل مختصر جداً وجميل .
لمعرفة عدد سجلات أحد الجداول نقوم بكتابة ما يلي ..
MyDS.Tables("Information").Rows.Count

لمعرفة القيمة المخزنة في الخلية الموجودة في الصف الأول والعمود الأول ، وعرضها في مربع رسالة ، نقوم بكتابة ما يلي ..
MsgBox(MyDS.Tables("Information").Rows(0).Item(0))

كما نستطيع أعادة كتابة الكود السابق ، بحيث نحدد فيه عمود محدد ، بكتابة ما يلي ..
MsgBox(MyDS.Tables("Information").Rows(0).Item("Name"))

لتغير قيمة الخلية الموجودة في الصف الأول والعمود المسمى Name ، نقوم بكتابة ما يلي ..
MyDS.Tables("Information").Rows(0).Item("Name")="Yaser"

لحذف السجل ( الصف ) الأول من الجدول ، نقوم بكتابة ما يلي ..
MyDS.Tables("Information").Rows(0).delete()

للتراجع عن التغيرات التي قمنا بها من تعديل وحذف ، نقوم بكتابة ما يلي ..
MyDS.Tables("Information").Rows(0).RejectChanges()

لإضافة سجل جديد ، نخزن البيانات التي نريدها في مصفوفة ، ونسندها للخاصية Add كما في الكود التالي ..
   Dim MyData() As String = {"Yaser", "32", "Gizan"}MyDS.Tables("Information").Rows.Add(MyData)

ويمكن تطوير الكود السابق باستخدام الكائن DataRow ، وتأهيله بصف جديد في الجدول المحدد ، وإدخال القيم فيه من خلال الخاصية Item ، ثم نسند الكائن DataRow إلى للخاصية Add التابعة لصفوف الجدول ، كما في الكود التالي ..
   Dim MyDR As DataRow = MyDS.Tables("Information").NewRow
   MyDR.Item("name") = "yaser mohamed"
   MyDR.Item("age") = "32"
   MyDR.Item("City") = "Gizan"
MyDS.Tables("Information").Rows.Add(mydr)

سنكتفي بذلك القدر ، وننتقل إلى التنقل بين السجلات ..
لمعرفة رقم موقع السجل الحالي وعرضه في مربع رسالة ، نكتب ما يلي ..
MsgBox(Me.BindingContext(MyDS, "Information").Position)

ولمعرفة عدد السجلات الموجودة في الجدول الحالي وعرضها في مربع رسالة ، نكتب ما يلي ..
MsgBox(Me.BindingContext(MyDS, "Information").Count)

وللانتقال للسجل الأول في الجدول نكتب ما يلي ..
Me.BindingContext(MyDS, "Information").Position = 0

وللانتقال للسجل الأخير في الجدول نكتب ما يلي ..
   Me.BindingContext(MyDS, "Information").Position = Me.BindingContext(MyDS, "Information").Count -1

وللانتقال للسجل التالي في الجدول نكتب ما يلي ..
   Dim MyPosition As Integer = Me.BindingContext(MyDS, "Information").PositionMe.BindingContext(MyDS, "Information").Position = MyPosition +1

وللانتقال للسجل السابق في الجدول نكتب ما يلي ..
   Dim MyPosition As Integer = Me.BindingContext(MyDS, "Information").PositionMe.BindingContext(MyDS, "Information").Position = MyPosition -1

** هنا ينتهي حديثنا اليوم ، فما أصبنا من صواب فمن الله وتوفيقه ، وما أصبنا من خطأ فمن أنفسنا والشيطان ، لذلك من وجد أي أخطاء فليصححها لنا مشكوراً ..
ولنأخذ قسطاً من الراحة ، لكي نستوعب هذه الجرعة من المعلومات ونصحح أخطائها إن وجدت ، ونعلق على الغير مفهوم منها ، و نكمل فيما بعد شرح ما تبقى من الدرس ، علماً أن موضوع درسنا القادم إن شاء الله هو الكائن DataAdapter ..
الخاصية Merge ( الدمج ) :
تقوم هذه الخاصية بدمج أو إضافة البيانات إلى الكائن DataSet من كائنات أخرى يمكن أن تكون مجمعة البيانات DataSet أو جدول DataTable أو مصفوفة البيانات DataRow ، ويملك الكائن المُدمَج عادةً بنية مشابهة للكائن DataSet الأصلية ، كمثال : إذا كان الكائن الجديد هو عبارة عن DataSet أخرى ، فإنه من الممكن أن يملك الجداول نفسها التي في DataSet الأولى ( الأصلية ) .
وطريقة استخدامها هي كالتالي :
1- عبارة عن دمج DataSet فرعية داخل DataSet أصلية ، ومثال ذلك ..
Dim MyDS As DataSetDim SubSet_DS As DataSetMyDS.Merge(dataSet)

2- عبارة عن دمج DataTable داخل DataSet أصلية ، ومثال ذلك ..
Dim MyDS As DataSetDim MyTable As DataTableMyDS.Merge(MyTable)

3- عبارة عن دمج DataRow داخل DataSet أصلية ، ومثال ذلك ..
Dim MyDS As DataSetDim Rows As DataRow()MyDS.Merge(Rows)

ومن المعلوم أن الكائن DataSet المولَّدة بواسطة الخاصية GetChange متوافقة مع DataSet الأصلية ( لاحتوائها على نفس التكوين و البنية ) . حيث يمكن للبرنامج على سبيل المثال استخدام الخاصية GetChange للحصول على كائن DataSet فرعي والمحتوي فقط على التغييرات ( أو الإضافات أو المحذوفات كما ذكرنا في الدروس السابقة ) ، ويمكنه بعد ذلك تثبيت التغييرات مع إمكانية تعديل بعض قيم البيانات ، ثم يحفظ التغييرات في قاعدة البيانات . وبعد انتهاء البرنامج من تحديث قاعدة البيانات ، فإن البرنامج يمكنه من خلال الخاصية Merge دمج التغييرات معيداً إياها إلى DataSet الأصلية ، وبالتالي فإنها ستكون متزامنة مع قاعدة البيانات . ويفرض علينا ذلك طبيعة البرنامج الذي نتعامل معه ، وخصوصاً في حالة احتوائه على تقيدات علائقية أو تقيدات أمنية معينه يحتاجها المبرمج ، ولكي تتضح الصورة فلنتأمل المثال التالي ( يحتاج هذا المثال إلى قراءة و فهم الدروس السابقة ) ..
Dim ds_Changes As New DataSet
   Dim ds_subset As New DataSet
   Dim MyCB As New OleDbCommandBuilder(MyDataAdapter)
   Me.BindingContext(MyDS, "Information").EndCurrentEdit()
         If MyDS.HasChanges Then
                 ds_Changes = MyDS.GetChanges
                 ds_subset = ds_Changes.GetChanges(DataRowState.Modified)
                 If (Not (ds_subset) Is Nothing) Then
                         MyDA.update(ds_subset.Tables("Information"))
                         MyDS.Merge(ds_subset)
                 End If
                 ds_subset = ds_Changes.GetChanges(DataRowState.Added)
                 If (Not (ds_subset) Is Nothing) Then
                         MyDA.update(ds_subset.Tables("Information"))
                         MyDS.Merge(ds_subset)
                 End If
                 ds_subset = ds_Changes.GetChanges(DataRowState.deleted)
                 If (Not (ds_subset) Is Nothing) Then
                         MyDA.update(ds_subset.Tables("Information"))
                         MyDS.Merge(ds_subset)
                 End If
                 MyDS.AcceptChanges()
  End If

و من باب العلم بالشيء ، الخاصية Merge تأخذ وسيطين اختياريين غير إلزاميين ، يخبرانها بكيفية الدمج ، الوسيط الأول هو قيمة منطقية ( Boolean ) وتحمل إما القيمة True أو القيمة False ، وتخبر الخاصية Merge فيما إذا يجب أن تُحافظ على التغييرات في DataSet الأصلي وذلك من خلال اختيار القيمة True ، أم لا وذلك من خلال اختيار القيمة False . الوسيط الثاني ويحمل أربع قيم ، من خلالها يخبر الخاصية Merge ماذا يتوجب عليها فعله عند فقدان جدول أو عمود ما في الـ DataSet الفرعية أو في الـ DataSet الأصلية ، حيث أنه عند استدعاء الخاصية Merge تقوم بالمقارنة بين مخططين الـ DataSet الأصلي والفرعي ، وذلك بسبب أنه من المحتمل أن ذلك المخططين قد يختلفان بسبب فقدان جدول أو عمود ما كما أسلفنا .
و ملخص هذه القيم ، مع طريقة استخدامها :-
1- القيمة MissingSchemaAction.Add :
تجعل الخاصية Merge تضيف الجدول أو العمود الجديد .
MyDS.Merge(ds_subset, False, MissingSchemaAction.Add
)
2- القيمة MissingSchemaAction.AddWithKey :
تجعل الخصية Merge تضيف أعمدة جديدة ومعلومات عن المفتاح الرئيسي عند الضرورة .
MyDS.Merge(ds_subset, False, MissingSchemaAction.AddWithKey)

3- القيمة MissingSchemaAction.Error :
تجعل الخاصية Merge تعلن عن أخطاء ، إذا لم تجد مطابقة البيانات الواردة مع بنية الـ DataSet الأصلية .
MyDS.Merge(ds_subset, False,  MissingSchemaAction.Error)

4- القيمة MissingSchemaAction.Ignore :
تجعل الخاصية Merge تتجاهل البيانات الجديدة إذا لم تتطابق مع الـ DataSet الأصلية .
MyDS.Merge(ds_subset, False, MissingSchemaAction.Ignore)

الخاصية Clone :
تنسخ هذه الخاصية نفس بنية الـ DataSet الأصلية إلى الـ DataSet الجديدة ، بحيث تمتلك نفس الجداول والتقيدات ، وطريقة استخدامها ..
Dim MyDS As New DataSet   Dim ds_subset As New DataSetds_subset = MyDS.Clone

الخاصية Copy :
تنسخ هذه الخاصية نفس بنية و بيانات الـ DataSet الأصلية إلى الـ DataSet الجديدة ، بحيث تمتلك نفس الجداول والتقيدات والبيانات أيضاً ، وبالتالي فإن Copy مشابهة لـ Clone ولكنها تتضمن البيانات ، وطريقة استخدامها ..
Dim MyDS As New DataSet   Dim ds_subset As New DataSetds_subset = MyDS.Copy

سبحانك اللهم وبحمدك، أشهد أن لا إله إلا أنت، أستغفرك وأتوب إليك


حررت من قبل: vb2005 في الأربعاء,06/جمادى الثانية/1431 هـ,11:52 مساءً


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالجمعة,08/جمادى الثانية/1431 هـ,12:55 صباحاً
المشاركة #4

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519



3 - الكائن DataAdapter :
في الدروس السابقة وضحنا العمل الذي يقوم به هذا الكائن ، حيث قلنا حينها أنه " بمثابة وسيط بين مجموعة البيانات "DataSet " ومصادر البيانات "Data Sources" ، حيث يقوم DataAdapter بعملية فتح الاتصال بقاعدة البيانات و استيراد وتصدير البيانات من و إلى مصدرها الأساسي ، وبعد تخزين البيانات في DataSet ، فإنها تصبح منفصلة عن مصدر البيانات ، لان الكائن DataAdapter يقوم بشكل تلقائي أيضاً بقطع الاتصال بقاعدة البيانات " ، ولكن هذا ليس كل شيء ، ما زلنا نحتفظ بالجزء الأفضل لدرس اليوم ...
يستخدم هذا الكائن كائنان صديقان تعرفنا عليهما فيما سبق ، وهما : الكائن OleDbConnection لإدارة اتصاله بقاعدة البيانات ( من فتح الاتصال و غلق الاتصال ) ، و الكائن OleDbCommand لإدارة استعلامات SQL البنيوية التي يجب تنفيذها ( من تحديد أو إضافة أو تعديل أو حذف ) . ولتجهيز هذا الكائن للعمل هناك أكثر من طريقة وجميعها جيده ، فقط على المبرمج أن يختار ما يناسبه منها ، والكود التالي يبين كيف يتم إنشاء ملائم بيانات ، واستخدام الكائن OleDbConnection لإدارة اتصاله بقاعدة البيانات ، وكذلك استخدام الكائن OleDbCommand لإدارة استعلام SQL والذي يقوم بتحديد مجموعة من الحقول المتوفرة في إحدى جداول قاعدة البيانات التي تم الاتصال بها ، وكذلك سوف نستخدم إحدى خصائص الكائن DataAdapter وهي selectCommand ولكنا لن نزعج أنفسنا بها هنا ، وسوف نشرحها بالتفصيل في وقت لاحق ، فقط نحتاج إلى القليل من التركيز لتأمل الكود التالي ..
' create the ConnectionString.
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
' create the selectCommand.
Dim selectCommand As OleDbCommand = New OleDbCommand("select * FROM Information")
               Dim instance_adapter As New OleDbDataAdapter()
instance_adapter.selectCommand = selectCommand
instance_adapter.selectCommand.Connection = selectConnection

ويمكن اختصار الكود السابق ليصبح كما يلي ..
' create the ConnectionString.
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
' create the selectCommand.
Dim selectCommand As OleDbCommand = New OleDbCommand("select * FROM Information", _           selectConnection)
Dim instance_adapter As New OleDbDataAdapter()instance_adapter.selectCommand = selectCommand

ويمكن اختصار الكود السبق أكثر من ذلك ليصبح كما يلي ..
Dim selectConnection As OleDbConnection = New OleDbConnection
 _        ("Provider=Microsoft.Jet.OLEDB.4.0;"
 _        & "Data Source=|DataDirectory|\Note.mdb;" 
_        & "User Id=admin;Jet OLEDB:Database Password=ado.net;")
Dim selectCommandText As String = "select * FROM Information"
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)

ويمكن اختصار الكود السبق أكثر من ذلك ليصبح كما يلي ..
Dim instance_adapter As New OleDbDataAdapter("select * FROM Information" _, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Note.mdb;" _& "User Id=admin;Jet OLEDB:Database Password=ado.net;")

ويتمتع هذا الكائن DataAdapter بالعديد من الخصائص ، ومن أهمها :-
* الخاصية Fill :
حيث تنقل البيانات من قاعدة البيانات (مصدرها الأساسي ) إلى DataSetأو DataTable ، وبعبارة أخرى القيام بعملية الاستيراد . والكود التالي يبين كيف يتم إنشاء الكائن DataAdapter وتجهيزه ، واستخدام الخاصية Fill لتعبئة الـ DataSet بالجدول المحدد في جملة الاستعلام ، ومن بعد ذلك نعرض مربع رسالة تخبرنا بعدد السجلات المتوفرة في الجدول الذي تم تخزينه في DataSet للتو ..

Dim selectCommandText As String = "select * FROM Information"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim MyDs As New DataSetinstance_adapter.Fill(MyDs)
MsgBox(MyDs.Tables(0).Rows.Count, MsgBoxStyle.Information)

في الحقيقة الخاصية Fill تأخذ الكثير من المتغيرات ( البارامترات ) ، سنتحدث عن أهمها ، وهو srcTable ومن خلاله نستطيع أن نضع اسم للجدول الذي نريد تخزينه في الـ DataSet وذلك من أجل الحصول على اسم ذو معنى أوضح ، وبدون هذا المتغير سوف يأخذ هذا الجدول الاسم "Table" ، وفي مثالنا السابق نستطيع استبدال السطر التاسع بالكود التالي لإعطاء الجدول اسم "Demo" ..
instance_adapter.Fill(ds, "Demo")

ولكي نتأكد من اسم الجدول الذي قمنا بتخزينه في الـ DataSet ، نكتب الكود التالي لعرض مربع رسالة تخبرنا باسم الجدول ..

MsgBox(ds.Tables(0).TableName)

ملاحظة :- الصورة الكاملة للمتغيرات ( البارامترات ) التي تأخذها الخاصية Fill ..
instance_adapter.Fill(MyDataSet As DataSet, startRecord  As Integer, maxRecords As Integer, srcTable As String)

حيث أن :
1- البارامتر MyDataSet يشير إلى الـ Dataset التي نريد تخزين الجدول بها .
2- البارامتر startRecord يشير إلى رقم السجل الذي نريد أن نبدأ به في تحميل البيانات ( يجب أن نعلم أن هذا الرقم يبدأ بالرقم صفر ويدل على السجل الأول ) من الجدول الذي نريد نسخ بياناته وتكوينه في الـ Dataset .
3- البارامتر maxRecords يشير إلى رقم السجل الذي نريد أن ننتهي عنده في تحميل البيانات من الجدول الذي نريد نسخ بياناته وتكوينه في الـ Dataset .
4- البارامتر srcTable يشير إلى الاسم المقترح للجدول الذي نريد تكوينه في الـ Dataset .
مثال :-
في المثال التالي لدينا جدول يحتوي على مجموعة من السجلات عددها 15 سجل ، ونريد أن نخزن تكوين وبيانات هذا الجدول في الـ DataSet ، ونريد أيضاً اختيار مجموعة محدده من السجلات ، على أن نبدأ من السجل الخامس ( بالطبع ترتيبه داخل السجلات يحمل الرقم 4 ) وننتهي إلى السجل العاشر ( بالطبع ترتيبه داخل السجلات يحمل الرقم 9 ) ، وبعد ذلك نريد أن نعطي هذا الجدول الاسم "Demo" ، وفي الأخير نعرض مربع رسالة تخبرنا بعدد السجلات في الجدول الذي تم تخزينه للتو ، وقيمة السجل الأول في العمود الأول من الجدول ..
Dim selectCommandText As String = "select * FROM Information order by name"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _ 
       & "User Id=admin;" _ 
       & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.Fill(ds, 4, 9, "Demo")
Dim strMsg As String = String.Format("Count of Records In The {0} Table = {1}.{2}The " _
& "First Value In The second Column Is : {3} .", _
ds.Tables(0).TableName, ds.Tables(0).Rows.Count, vbNewLine, _
 ds.Tables(0).Rows(0).Item(0)
MsgBox(strMsg, MsgBoxStyle.Information)

(( يمكن تغيير الأرقام ومشاهدة النتائج المختلفة ))

* الخاصية TableMappings :
عندما يختار DataAdapter بياناته من قاعدة البيانات بواسطة جملة الاستعلام للمرة الأولى ، فإنه يخزنها في الـ DataSet ضمن جدول يحمل اسم افتراضي Table بشكل تلقائي ، وأي تحميل آخر للبيانات في الـ DataSet فإنها سوف تخزن ضمن جداول تحمل اسم table1 ، Table2 ، ... وهكذا ، و هذا الاسم كما يبدو لا يدل على اسم ذو معنى واضح ، ونستطيع من خلال TableMappings تحويله إلى اسم ذو معنى أوضح ، ولعل التمثيل الذي في الصورة التالية يوضح الفكرة ...


ولكي نقوم بذلك نحتاج إلى تمرير متغيرين من نوع String للخاصية Add التابعة للخاصية TableMappings ، الأول SourceTable وهو اسم الجدول الافتراضي ، والثاني DataSetTable وهو الاسم الذي نريده للجدول الذي يجب أن يستقبل البيانات في الـ DataSet .
ومثال على ذلك :
الكود التالي يبين كيف يتم إنشاء الكائن DataAdapter وتجهيزه ، واستخدام الخاصية TableMappings لتغيير اسم الجدول الذي يجب أن يستقبل البيانات داخل الـ DataSet وفي النهاية نعرض مربع رسالة توضح اسم الجدول مع عدد سجلاته ..
Dim selectCommandText As String = "select * FROM [Information]"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.TableMappings.Add("Table", "Info")
instance_adapter.Fill(ds)
Dim strMsg As String = String.Format("Count of Records In The {0} Table = {1} .", _        ds.Tables(0).TableName, ds.Tables(0).Rows.Count)
MsgBox(strMsg, MsgBoxStyle.Information)


ملاحظة هامة : (( لو كان الأمر مجرد تغير اسم الجدول ، فإنه يغنينا عن كل هذا العناء ، مجرد كتابة الاسم المقترح للجدول خلال استدعاء الخاصية Fill كما ذكرنا سابقاُ ، وهذه هي الإعادة للكود اللازم لعمل مثل ذلك ..
instance_adapter.Fill(ds, "Demo")

هذا رائي الشخصي )) .

ليس ذلك فقط بل نستطيع كذلك تغيير أسماء الحقول ( الأعمدة ) الموجودة دخل الجدول إلى أسماء ذو معنى أوضح ، وذلك من خلال الخاصية ColumnMappings التابعة للخاصية TableMappings ، وهي أيضاً تحتاج إلى تمرير متغيرين من نوع String للخاصية Add التابعة لها ، الأول SourceColumn وهو اسم العمود الأساسي في قاعدة البيانات ، والثاني DataSetColumn وهو الاسم الجديد الذي نريده للعمود في الجدول المخزن في الـ DataSet .
ولعل التمثيل الذي في الصورة التالية يوضح الفكرة ...


ومثال على ذلك :
الكود التالي يبين كيف يتم إنشاء الكائن DataAdapter وتجهيزه ، واستخدام الخاصية TableMappings لتغيير اسم الجدول الذي يجب أن يستقبل البيانات داخل الـ DataSet ، ويلي ذلك نقوم باستخدام الخاصية ColumnMappings لتغيير أسماء بعض الحقول ( علماً أننا سوف نشير للجدول الافتراضي Table بالرمز (0) وذلك كي نخبر هذه الخاصية أننا نريد أن يتم إجراء التعديلات عليه )، وفي النهاية نعرض مربع رسالة توضح اسم الجدول مع عدد سجلاته ، واسم العمود الثاني في الجدول ..
Dim selectCommandText As String = "select * FROM [Information]"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _ 
       & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.TableMappings.Add("Table", "Info")instance_adapter.TableMappings(0).ColumnMappings.Add("Name", "First Name")instance_adapter.TableMappings(0).ColumnMappings.Add("ID", "InfoID")instance_adapter.Fill(ds)
Dim strMsg As String = String.Format("Count of Records In The {0} Table = {1} .{2}The          name Of the second Column Is It : {3} ."), _
        ds.Tables(0).TableName, ds.Tables(0).Rows.Count, vbNewLine,              ds.Tables(0).Columns(0).ColumnName )
MsgBox(strMsg, MsgBoxStyle.Information)


ملاحظة هامة : (( لو كان الأمر مجرد تغير أسماء الأعمدة ، فإنه يغنينا عن كل هذا العناء ، مجرد كتابة عبارة AS في جملة الاستعلام ، وهذا هو الكود اللازم لعمل مثل ذلك ..

Dim selectCommandText As String = "select ID AS [Info ID], Name AS [First Name] FROM [Information]"
هذا رائي الشخصي )) .

وهناك استخدامات أخرى ، مثالاً على ذلك لو أننا أردنا تحميل البيانات من جدولين مختلفين من خلال DataAdapter واحد ، وللقيام بذلك علينا أن نتأمل المثال التالي حيث يقوم بتوضيح الفكرة :
في البداية يتم إنشاء الكائن DataAdapter وتجهيزه ، واستخدام الخاصية TableMappings لتغيير اسم الجدول الأول ( وليكن أسمة Info ) الذي يجب أن يستقبل البيانات داخل الـ DataSet ، ويلي ذلك نقوم باستخدام الخاصية ColumnMappings لتغيير أسماء بعض الحقول ( علماً أننا سوف نشير للجدول الافتراضي Table بالرمز (0) وذلك كي نخبر هذه الخاصية أننا نريد أن يتم إجراء التعديلات عليه )، وبعد ذلك نستدعي الخاصية Fill لتحميل البيانات ، ثم نغيِّر القيمة DataSetTable الخاصة TableMappings إلى اسم الجدول الثاني ، والذي سوف نعطيه الاسم Note ( كل ذلك يتم داخل الـ DataSet ) ، ونقوم بتغيير اسم أحد حقوله ، وبعد ذلك نكتب جملة الاستعلام التي نريدها أن تحظر لنا بيانات الجدول الثاني من مصدر قاعدة البيانات ، وعندما نستدعي مرة أخرى الخاصية Fill فإن البيانات الجديدة ستذهب مباشرة إلى الجدول المسمى Note ، وبذلك نكون قد حصلنا على جدولين من خلال DataAdapter واحد ، وفي نهاية المطاف كي نتأكد من صحة التغييرات والمدخلات ، نعرض مربع رسالة تخبرنا ببعض التفاصيل المتعلقة بالجدولين ..
Dim selectCommandText As String = "select * FROM [Information]"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.TableMappings.Add("Table", "Info")instance_adapter.TableMappings(0).ColumnMappings.Add("Name", "FirstName")instance_adapter.TableMappings(0).ColumnMappings.Add("ID", "InfoID")instance_adapter.Fill(ds)
instance_adapter.TableMappings(0).DataSetTable = "Note"
instance_adapter.TableMappings(0).ColumnMappings.Add("Note", "MyNote")instance_adapter.selectCommand.CommandText = "select * FROM [Note]"
instance_adapter.Fill(ds)
Dim strMsg As String = String.Format("Count of Records In The {0} Table = {1} ." _        & "{2} The name Of the second Column Is It : {3} ." _
        & "{4}Count of Records In The {5} Table = {6} ." _
        & "{7} The name Of the second Column Is It : {8} .", _
        ds.Tables(0).TableName, ds.Tables(0).Rows.Count, vbNewLine, _        ds.Tables(0).Columns(0).ColumnName, _ 
       vbNewLine, ds.Tables(1).TableName, ds.Tables(1).Rows.Count, vbNewLine, _        ds.Tables(1).Columns(1).ColumnName)
MsgBox(strMsg, MsgBoxStyle.Information)


* الخاصية FillSchema :
تجعل هذه الخاصية الخاصة بالكائن DataAdapter يحمل بنية البيانات الموجودة في الجدول المختار إلى الكائن DataSet بدون تحميل أية بيانات ، وبعبارة أخرى هذه الخاصية مشابهة للخاصية Fill ولكنها لا تنسخ البيانات معها . ولها ثلاثة متغيرات ( بارامترات ) :
- المتغير الأول هو الـ DataSet.
- المتغير الثاني هو SchemaType ومن خلاله نخبر هذه الخاصية فيما إذا كان يتوجب عليها استخدام TableMappings الخاص بالكائن DataAdapter أم لا ، و لهذا المتغير قيمتين تتحكم في ذلك الأولى Mapped ( ينصح في استخدامه في الغالب ) وهي تجعل DataAdapter يستعمل البنية التي حددت له من قبل TableMappings . والقيمة الثانية هي Source وهي تجعل DataAdapter يتجاهل البنية التي حددت له من قبل TableMappings وينشئ بنية تطابق بنية قاعدة البيانات .
- المتغير الثالث إختياري وهو srcTable يشير إلى الاسم المقترح للجدول الذي نريد نسخ تكوينه في الـ Dataset بغض النظر عن قيمة SchemaType .
ومثال على ذلك :
الكود التالي يبين كيف يتم إنشاء الكائن DataAdapter وتجهيزه ، واستخدام الخاصية FillSchema لتعبئة الـ DataSet بالجدول المحدد في جملة الاستعلام ) بدون تحميل أي بيانات ) ، وسوف نستخدم المتغير SchemaType.Mapped لكي نجعل DataAdapter يستعمل البنية التي حددت له من قبل TableMappings ، ومن بعد ذلك نعرض مربع رسالة تخبرنا بعدد السجلات المتوفرة في الجدول الذي تم تخزينه في DataSet للتو وذلك للتأكد من أنها تساوي صفراً ..
Dim selectCommandText As String = "select * FROM Information"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _ 
       & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.TableMappings.Add("Table", "Demo")instance_adapter.TableMappings(0).ColumnMappings.Add("Name", "FirstName")instance_adapter.FillSchema(ds, SchemaType.Mapped)
Dim strMsg As String = String.Format("Count of Records In The {0} Table = {1} .", _ds.Tables(0).TableName, ds.Tables(0).Rows.Count)
MsgBox(strMsg, MsgBoxStyle.Information)

ولو أردنا من الخاصية FillSchema أن تجعل DataAdapter يستعمل البنية التي حددت له من قبل TableMappings ، مع إعطاء الجدول اسم مختلف ، نستبدل السطر رقم 11 بالكود التالي ..
instance_adapter.FillSchema(ds, SchemaType.Mapped , "Info")


ولو أردنا من الخاصية FillSchema أن تتجاهل البنية التي حددت له من قبل TableMappings وتنشئ بنية تطابق بنية قاعدة البيانات ، نستبدل السطر رقم 11 بالكود التالي ..
instance_adapter.FillSchema(ds, SchemaType.Source)

في هذه الحالة سوف يصبح اسم الجدول داخل الـ DataSet الاسم الافتراضي Table .

ولو أردنا من الخاصية FillSchema أن تتجاهل البنية التي حددت له من قبل TableMappings وتنشئ بنية تطابق بنية قاعدة البيانات ، مع إعطاء الجدول اسم ذو معنى أوضح ، نستبدل السطر رقم 11 بالكود التالي ..
instance_adapter.FillSchema(ds, SchemaType.Source , "Demo")


** هنا ينتهي حديثنا اليوم ، فما أصبنا من صواب فمن الله وتوفيقه ، وما أصبنا من خطأ فمن أنفسنا والشيطان ، لذلك من وجد أي أخطاء فليصححها لنا ، أو يخبرنا به كي نصححه ، مشكوراً ..
ولنأخذ قسطاً من الراحة ، لكي نستوعب هذه الجرعة من المعلومات ونصحح أخطائها إن وجدت ، ونعلق على الغير مفهوم منها ، و نكمل فيما بعد شرح ما تبقى من الدرس ، ونظراً لأن الحديث عن الكائن DataAdapter طويل و ممتع فلقد قمنا للتو بشرج جزء ، وفي موضوع درسنا القادم إن شاء الله سوف نكمل الجزء الآخر وهو الحديث عن الخاصية update وما يلحق بها ..
الخاصية update :
تجعل هذه الخاصية الكائن DataAdapter ينسخ التغييرات بشكل عكسي من الكائن DataSet إلى مصدر قاعدة البيانات ، وذلك من خلال تنفيذ الأوامر insertCommand ، updateCommand ، deleteCommand وذلك لكل أسطر DataSet ألتي قد أدخلت أو عدلت أو حذفت . و سوف نقوم بشرح كل واحد من هذه الأوامر على حده ونبين كيف يعمل ، علماً أنه يمكننا استخدام باني الأوامر CommandBuilder ليقوم هو ببناء الأوامر اللازمة والتي سبق ذكرها نيابة عنا ، وهو أيضاً سوف نقوم بشرحه بالتفصيل .
كما نعلم ربما يحتوي الـ Dataset إلى أكثر من جدول ، لذلك للقيام بعملية التحديث نحتاج إلى تحديد الجدول الذي نرغب في تحديثه كما في المثال ..
instance_adapter.update(ds, "Information")

أو الكود التالي ..
instance_adapter.update(ds.Tables("Information"))

أو الكود التالي في حالة معرفتنا بالرقم ألفهرسي للجدول المخزن في الـ DataSet ..
instance_adapter.update(ds.Tables(0))

ملاحظة هامة :
إذا استخدمت الخاصية TableMappings لتغيير الاسم لجدول أو لأعمدة جدول ما عند تحميل البيانات ، فكن متأكداً من استخدام نفس التحويلات عند القيام بعملية التحديث .
- الأمر insertCommand :
يعد أمر الإضافة insertCommand أحد خصائص الكائن DataAdapte و عمله الأساسي هو إضافة سجل جديد إلى سجلات الجدول ، والطريقة التي يعمل بها مشابهة تماماً لكائن الأمر الذي قد تحدثنا عنه في الوضع المتصل ، والمثال التالي موضح بالشرح ، حيث أنه في البداية سوف نقوم بتجهيز الكائنات للعمل ، ثم نملأ الـ DataSet بالبيانات ، و نقوم بتحديث بياناته ، ثم نقوم بنسخ التغييرات التي طرأت على الـ DataSet بشكل عكسي من الكائن DataSet إلى مصدر قاعدة البيانات ، من خلا الكائن DataAdapter وكائن الأمر insertCommand التابع له ، وفي الأخير نستخدم الخاصية update لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
 Dim selectCommandText As String = "select * FROM Information;"
 Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
 Dim ds As New DataSet
 instance_adapter.Fill(ds, "Information")
Dim MyDR As DataRow = ds.Tables("Information").NewRow
MyDR.Item("Name") = "Yaser Mohamed"
MyDR.Item("Age") = "32"
MyDR.Item("Phone") = "0123456789"
MyDR.Item("Email") = "Yaser1395@hotmail.com"
ds.Tables("Information").Rows.Add(MyDR)
Dim insertCommand As New OleDbCommand
insertCommand.Connection = selectConnection
insertCommand.CommandText = "insert INTO Information ([Name],[age],[phone],[email]) VALUES (?,?,?,?)"
insertCommand.CommandType = CommandType.Text
insertCommand = insertCommand
insertCommand.Parameters.AddWithValue("?", "Yaser Mohamed")
insertCommand.Parameters.AddWithValue("?", "32")
insertCommand.Parameters.AddWithValue("?", "0123456789")
insertCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
instance_adapter.insertCommand = insertCommand
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("update Successfully...", MsgBoxStyle.Information)

شرح الكود السابق متزامن مع أرقام الأسطر :
1- التصريح عن متغير للإستعلام عن الجدول المخزن في مصدر البيانات ( Data Sources ) .
2- التصريح عن متغير لكائن الإتصال بقدعدة البيانات .
7- التصريح عن متغير للكائن DataAdapter ( وهو الوسيط بين الكائن DataSet و مصدر البيانات ) و تجهيزه .
8- التصريح عن متغير الكائن DataSet .
9- استيراد البيانات من مصدر البيانات ، وتعبئتها في جدول محدد ضمن الكائن DataSet .
10- الكود اللازم لإضافة سجل جديد إلى سجلات الجدول المخزن في الكائن DataSet ، حيث يبدأ بالتصريح عن متغير كائن صف ، وتجهيزه من خلال ربطه بالجدول الموجود في الكائن DataSet ، ثم استدعاء الخاصية صف جديد .
11- بعد ذلك نقوم بإسناد البيانات المحدثه إلى الحقول الخاصة بالجدول ويتكرر ذلك في كل من الاسطر رقم ( 11 إلى 14 ) .
15- نقوم بإضافة كائن الصف إلى صفوف الجدول الموجود في الكائن DataSet، وبذلك نكون قد حدثنا الجدول المخزن في الكائن DataSet .
16- ولكي نقوم بتصدير البيانات الجديده من الكائن DataSet إلى مصدر البيانات ، نحتاج إلى اعداد وتجهيز كائن الأمر الخاص بإضافة صف جديد ، وذلك من خلال إنشاء كائن أمر وإعداده كما كنا نعمل في الوضع المتصل ، وذلك نجده في كل من الاسطر رقم ( 16 إلى 24 ) .
25- بعد ذلك نقوم بإسناد كائن الأمر إلى الخاصية الخاصة بأمر الإضافة في الكائن DataAdapter .
26- وللقيام بعملية التحديث النهائية لمصدر البيانات نحتاج إلى إيقاف عملية التحديث على الجدول المطلوب ضمن الكائن DataSet ، وذلك حفاظاً على تزامن البيانات .
27- هنا نقوم بعملية التحديث بعد تحديد اسم الجدول الذي نرغب في تحديثه .
28- مربع رسالة تخبرنا بنجاح العملية .
ويكمن كتابة الكود السابق بشكل أخر وسوف يؤدي نفس النتيجة ، فلنتأمل الكود التالي ..
 Dim selectCommandText As String = "select * FROM Information;"
 Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
 Dim ds As New DataSet
 instance_adapter.Fill(ds, "Information")
Dim MyDR As DataRow = ds.Tables("Information").NewRow
MyDR.Item("Name") = "Yaser Mohamed"
MyDR.Item("Age") = "32"
MyDR.Item("Phone") = "0123456789"
MyDR.Item("Email") = "Yaser1395@hotmail.com"
ds.Tables("Information").Rows.Add(MyDR)
instance_adapter.insertCommand = New OleDbCommand("insert INTO Information ([Name],[age],[phone],[email]) VALUES (?,?,?,?)" , selectConnection)
instance_adapter.insertCommand.Parameters.Clear()
instance_adapter.insertCommand.Parameters.AddWithValue("?", "Yaser Mohamed")
instance_adapter.insertCommand.Parameters.AddWithValue("?", "32")
instance_adapter.insertCommand.Parameters.AddWithValue("?", "0123456789")
instance_adapter.insertCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("update Successfully...", MsgBoxStyle.Information)

شرح الكود السابق مطابق للشرح الذي يسبقه ما عدا بعض الاختلافات التي سوف نوضحها هنا ، وهي متزامنة مع أرقام الأسطر :
16- ولكي نقوم بتصدير البيانات الجديده من الكائن DataSet إلى مصدر البيانات نحتاج إلى اعداد وتجهيز كائن الأمر insertCommand التابع للكائن DataAdapter والخاص بإضافة صف جديد وذلك من خلال إسناد كائن أمر جديد وإعداده بجملة SQL اللازمة لعملية الإضافة ، و كائن الاتصال اللازم أيضاً .
17- بعد ذلك نحتاج إلى إضافة البارامترات التي تم تعشيشها في جملة SQL السابقة الذكر ، مع قيمها المحدثة ، وذلك نجده في كل من الأسطر رقم ( 17 إلى 21 ) .
- الأمر deleteCommand :
يعد أمر الحذف deleteCommand أحد خصائص الكائن DataAdapte و عمله الأساسي هو حذف سجل من سجلات الجدول ، والطريقة التي يعمل بها مشابهة تماماً لكائن الأمر الذي قد تحدثنا عنه في الوضع المتصل ، حيث سنحتاج إلى وجود فقرة Where في جملة SQL والتي تشير إلى بارامتر ( معامل ) يساعدنا في تحديد السجل المطلوب حذفه ، والمثال التالي موضح بالشرح ، حيث أنه في البداية سوف نقوم بتجهيز الكائنات للعمل ، ثم نملأ الـ DataSet بالبيانات ، و نقوم بحذف السجل الحالي من الجدول المخزن في الكائن DataSet ( تعتبر عمليه الحذف هذه تحديث للسجلات الموجودة في الجدول المخزن في الكائن DataSet ) ، ثم نقوم بنسخ التغييرات التي طرأت على الـ DataSet بشكل عكسي من الكائن DataSet إلى مصدر قاعدة البيانات ، وذلك من خلا الكائن DataAdapter وكائن الأمر deleteCommand التابع له ، وفي الأخير نستخدم الخاصية update لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
 Dim selectCommandText As String = "select * FROM Information order by name"
 Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.Fill(ds, "Information")
Dim MYPosition As String = Me.BindingContext(ds, "Information").Position
Dim IdValue As String = ds.Tables("Information").Rows(MYPosition).Item("ID")Me.BindingContext(ds, "Information").RemoveAt(MyPosition)
instance_adapter.deleteCommand = New OleDbCommand("delete FROM Information WHERE  Information.ID=?;", selectConnection)
instance_adapter.deleteCommand.Parameters.Clear()
instance_adapter.deleteCommand.Parameters.AddWithValue("?",IdValue)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("deleteD Successfully...", MsgBoxStyle.Information)

شرح الكود السابق ينطبق عليه بعض الشروحات التي سبق ذكرها ، لذا سنكتفي بشرج ما جد من الكود ، وهو متزامن مع أرقام الأسطر :
10- نقوم بتخزين الرقم الذي يعبّر عن موضع السجل الحالي في الجدول المخزن داخل الكائن DataSet ، وذلك من أجل عملية الحذف من داخل الـ DataSet .
11- نقوم بتخزين قيمة رقم الحقل المسمى "ID" الخاص بالسجل الحالي للجدول المخزن داخل الكائن DataSet ، وذلك من أجل عملية الحذف من مصدر قاعدة البيانات .
12- نقوم هنا باستخدام الأمر RemoveAt لحذف السجل الحالي ( والذي قمنا بتخزين قيمته في المتغير MYPosition ) من الجدول المخزن في الكائن DataSet والذي قمنا بتحديد اسمه ، عندئذ يتم حذف السجل من داخل الـ DataSet فقط .
13- ولكي نقوم بتصدير البيانات المحدثة من الكائن DataSet إلى مصدر البيانات نحتاج إلى إعداد وتجهيز كائن الأمر deleteCommand التابع للكائن DataAdapter والخاص بحذف سجل ، وذلك من خلال إسناد كائن أمر جديد وإعداده بجملة SQL اللازمة لعملية الحذف ، و كائن الاتصال اللازم أيضاً .
14- بعد ذلك نحتاج إلى إضافة البارامتر الذي تم تعشيشه في جملة SQL السابقة الذكر ، مع قيمته والتي قمنا بتخزينها سابقاً في المتغير MyFieldValue ، وذلك نجده في كل من السطرين رقم ( 14 ، 15 ) .
- الأمر updateCommand:
يعد أمر التحديث updateCommand أحد خصائص الكائن DataAdapte و عمله الأساسي هو تحديث سجل محدد من سجلات الجدول ، والطريقة التي يعمل بها مشابهة تماماً لكائن الأمر الذي قد تحدثنا عنه في الوضع المتصل ، حيث سنحتاج إلى وجود فقرة Where في جملة SQL والتي تشير إلى بارامتر ( معامل ) يساعدنا في تحديد السجل المطلوب تحديثه ، والمثال التالي موضح بالشرح ، حيث أنه في البداية سوف نقوم بتجهيز الكائنات للعمل ، ثم نملأ الـ DataSet بالبيانات ، و نقوم بعد ذلك بتحديث بيانات السجل الحالي للجدول المخزن في الكائن DataSet ، ثم نقوم بنسخ التغييرات التي طرأت على الـ DataSet بشكل عكسي من الكائن DataSet إلى مصدر قاعدة البيانات ، وذلك من خلا الكائن DataAdapter وكائن الأمر updateCommand التابع له ، وفي الأخير نستخدم الخاصية update لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
 Dim selectCommandText As String = "select * FROM Information"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.Fill(ds, "Information")
Dim MyPosition As Integer = Me.BindingContext(ds, "Information").Position
Dim IdValue As String = ds.Tables(0).Rows(MyPosition).Item("ID")
ds.Tables(0).Rows(MyPosition).Item("Name") = "Yaser AL-Shikh"
ds.Tables(0).Rows(MyPosition).Item("Age") = "32"
ds.Tables(0).Rows(MyPosition).Item("Phone") = "123456789"
ds.Tables(0).Rows(MyPosition).Item("Email") = "Yaser1395@hotmail.com"
instance_adapter.updateCommand = New OleDbCommand("update Information set Name=?, Age=?, Phone=?, Email=? WHERE Id =?", selectConnection)
instance_adapter.updateCommand.Parameters.Clear()
instance_adapter.updateCommand.Parameters.AddWithValue("?", "Yaser AL-Shikh")
instance_adapter.updateCommand.Parameters.AddWithValue("?", "25")
instance_adapter.updateCommand.Parameters.AddWithValue("?", "123456789")instance_adapter.updateCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
instance_adapter.updateCommand.Parameters.AddWithValue("?", IdValue)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds.Tables("Information"))
MsgBox("update Successfully...", MsgBoxStyle.Information)

شرح الكود السابق ينطبق عليه بعض الشروحات التي سبق ذكرها ، لذا سنكتفي بشرج ما جد من الكود ، وهو متزامن مع أرقام الأسطر :
12- نقوم هنا بتحديث حقول السجل الحالي ( Name , Age ,Phone , Email ) في الجدول المخزن داخل الكائن DataSet ، وذلك نجده في كل من السطور رقم ( 12 ، 15 )
16- ولكي نقوم بتصدير البيانات المحدثة من الكائن DataSet إلى مصدر البيانات نحتاج إلى إعداد وتجهيز كائن الأمر updateCommandالتابع للكائن DataAdapter والخاص بتحديث سجل ، وذلك من خلال إسناد كائن أمر جديد وإعداده بجملة SQL اللازمة لعملية التحديث ، و كائن الاتصال اللازم أيضاً .
17- بعد ذلك نحتاج إلى إضافة البارامترات التي تم تعشيشها في جملة SQL السابقة الذكر ، مع قيمها الخاصة بها ، وكذلك البارامتر الخاص بتحديد السجل المراد تحديثه والذي قمنا بتخزين قيمته سابقاً في المتغير IdValue ، وكل ذلك نجده في السطور رقم ( 17 إلى 22 ) .
وقبل أن نختم الحديث عن عملية التحديث باستخدام الخاصية update أريد أن أبين أنه عند قيام هذا الأمر بالعمل فإنه يقوم باختبار حالة الصف ، ويقوم بتنفيذ الأمر المطلوب سواء كان إضافة أو تحديث أو حذف ، وذلك بشكل متكرر لكل صف من الصفوف ، حيث أن تحديث الصفوف لا يتم دفعة واحده ، إنما يتم تحديث كل صف بشكل منفرد .
وبمجرد استدعاء هذه الخاصية تقوم بتنفيذ سبعة أمور تتم خلف الكواليس بشكل متلاحق ، كنت قد أشرت إليها في إحدى ردودي على الأخ abetry ، وهي كما يلي على التوالي ..
1. القيم التي أدخلت في DataRow للكائن DataSet تَنتقلُ إلى قِيَم البارامترات التي تم وضعها في جُمل SQL الخاصة بالتحديث ( الإضافة أو التعديل أو الحذف ) سواء تم بناء هذه الجمل من قبل CommandBuilder أو التي وضعت من قبل المبرمج بشكل يدوي .
2. يبدأ الحدث OnRowUpdating في الإقلاع .
3. يتم تنفيذ أمر التحديث الذي تم كتابته في جملة SQL ( سواء كان هذا التحديث للإضافة أو التعديل أو الحذف ) .
4. إذا الأمر أعد لإرْجاع السجلِ الأول ، فإن النتيجة الأولى التي تعود يكون موقعها في الـ DataRow . *
5. إذا كان هناك بارامترات ناتجه، فإنهم يوضُوعون في الـ DataRow. *
6. يبدأ الحدث OnRowupdated في الإقلاع .
7. يتم استدعاء الخاصية AcceptChanges من الكائن DataSet .
* رقمي ( 4 ، 5 ) لست على دراية تامة بها ولكني نقلتها بعد أن قمت بترجمتها من MSDN لعله يوجد من يستفيد منها أو يوضحها لنا ، ونصها الأساسي هو :

LEFT TO RIGHT

4- If the command is set to FirstReturnedRecord, the first returned result is placed in the DataRow.
5- If there are output parameters, they are placed in the DataRow.


ملاحظة هامة : يمكن التوسع في هذا الأمر ، ولكنا سنكتفي بهذا الحد من المعلومات ، ومن الجدير بالذكر أننا لم نستخدم بعد عناصر التحكم المترابطة ، وكذلك باني الأوامر الكائن CommandBuilder والكائنات الأخرى ، والتي تختصر لنا الكود بنسبة مرضية جداً ، بالإضافة إلى المرونة وقوة التحكم ، من أجل ذلك نجد هنا أن الكود طويل ( أرجو أن نصبر قليلاً فهو في حقيقة الأمر اقل بكثير مما هو عليه) ، علماً أن الكود المذكور من أجل الشرح والفهم لما يدور خلف الكواليس فقط ، وسوف نعيد كتابة الاكواد السابقة بشكل مختصر ، وذلك عندما نتقدم في الدرس قليلاً ..

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

ملاحظة : موضوعنا القادم سوف يكون الكائن CommandBuilder ، وسوف نتعلم كيف يختصر لنا هذا الكائن الكثير من الأكواد السابقه ، كما سنشاهد كيف يقوم هذا الكائن ببناء الأوامر الخاصة بالتحديث ..


حررت من قبل: vb2005 في الجمعة,08/جمادى الثانية/1431 هـ,03:39 صباحاً


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالسبت,09/جمادى الثانية/1431 هـ,11:57 صباحاً
المشاركة #5

خبيرتحليل نظم و دوت نت
الرتبة في المنتدى:عماد

أيقونة المجموعة

المجموعة: مشرفي الموقع
المشاركات: 3849
سجل في:الأحد,17/محرم/1428 هـ,05:57 صباحاً
الدولة:الأردن
رقم العضوية: 19244






بارك الله فيك وجزاك الله خير ،


شرح موفق ، وياريت تقوم بعمل امثله بسيطه على كل امر من هذه الاوامر وارفاقها حتى تتم وتعم الفائدة ،

وان شاء الله عندما يكتمل الشرح ساقوم بتثبيت هذه المشاركة.


تحياتي للجميع
ابو سامر


حررت من قبل: jbsa في السبت,09/جمادى الثانية/1431 هـ,05:10 مساءً
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالسبت,09/جمادى الثانية/1431 هـ,03:11 مساءً
المشاركة #6

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519




شكرا اخي الفاضل جهاد ابوسامر هذا العلم من بعض ماعندكم زادنا الله من نعمه ووفقنا


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالسبت,09/جمادى الثانية/1431 هـ,03:37 مساءً
المشاركة #7

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519



الكائن CommandBuilder :
من المعلوم أن الكائن DataAdapter يستخدم كائنات الأوامر ( selectCommand ، insertCommand ، updateCommand ، deleteCommand ) لاختيار أو إضافة أو تحديث أو حذف السجلات في قاعدة البيانات ، وحيث أنه يجب على هذه الكائنات استخدام الكائن OleDbParamter ( أو SqlParamter ) لتحديد القيم التي يجب استخدامها لمعالجة قاعدة البيانات ، فإنه ولحسن الحظ لا يتوجب علينا إنشاء تلك الكائنات ( الإضافة أو التحديث أو الحذف وكذلك البارامترات ) بأنفسنا ، وذلك عندما نستخدم الكائن CommandBuilder ( والذي يسمى باني الأوامر ) و القيام بربطه بالكائن DataAdapter ، حيث سوف يتولى هو بإعداد الأوامر اللازمة و البارامترات المناسبة .
وطرقة تجهيزه للعمل بسيطة جداً ، وهي كما في الكود التالي ..
Dim MyComB As New OleDbCommandBuilder
MyComB.DataAdapter = instance_adapter

ويمكن اختصارها بالشكل التالي ..
Dim MyComB As New OleDbCommandBuilder(instance_adapter)


- ويبين الكود التالي كيف يمكن استخدام CommandBuilder لصنع كائن أمر DataAdapter لإضافة سجل جديد ..
وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديلات الجديدة ، وهي ربط الكائن CommandBuilder بالكائن DataAdapter ، وفي السطر الأخير نعرض MsgBox نعرض فيها جملة SQL التي قام CommandBuilder ببنائها وكذلك عدد البارامترات التي استخدمها ..
Dim selectCommandText As String = "select * FROM Information;"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSet
instance_adapter.Fill(ds, "Information")
Dim MyDR As DataRow = ds.Tables("Information").NewRow
MyDR.Item("Name") = "Osamh Mohamed"
MyDR.Item("Age") = "18"
MyDR.Item("Phone") = "0123456789"
MyDR.Item("Email") = "Osamh@hotmail.com"
ds.Tables("Information").Rows.Add(MyDR)
Dim MyComB As New OleDbCommandBuilder(instance_adapter)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("update Successfully...", MsgBoxStyle.Information)
MessageBox.Show(String.Format("The SQL insertCommand Is :{0}{1}{2}{3}{4}The Count Of Paramters Is: {5}", vbNewLine, vbNewLine, MyComB.GetinsertCommand().CommandText, vbNewLine, vbNewLine, MyComB.GetinsertCommand().Parameters.Count))


بعد تنفيذ الكود السابق سوف نشاهد أن الكائن CommandBuilder كون لنا جملة SQL الخاصة بإضافة سجل جديد بشكل احترافي ، وأن عدد البارامترات التي استخدمها 4 ..
insert INTO Information (Name, Age, Phone, Email) VALUES (?, ?, ?, ?)



- ويبين الكود التالي كيف يمكن استخدام CommandBuilder لصنع كائن أمر DataAdapter لحذف سجل ..
وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديلات الجديدة ، وهي ربط الكائن CommandBuilder بالكائن DataAdapter ، وفي السطر الأخير نعرض MsgBox نعرض فيها جملة SQL التي قام CommandBuilder ببنائها وكذلك عدد البارامترات التي استخدمها ..
Dim selectCommandText As String = "select * FROM Information order by name"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSetinstance_adapter.Fill(ds, "Information")
Dim MYPosition As String = Me.BindingContext(ds, "Information").Position
Me.BindingContext(ds, "Information").RemoveAt(MYPosition)
Dim MyComB As New OleDbCommandBuilder(instance_adapter)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("deleteD Successfully...", MsgBoxStyle.Information)
MessageBox.Show(String.Format("The SQL deleteCommand Is :{0}{1}{2}{3}{4}The Count Of Paramters Is: {5}", vbNewLine, vbNewLine, MyComB.GetdeleteCommand().CommandText, vbNewLine, vbNewLine, MyComB.GetdeleteCommand().Parameters.Count))
بعد تنفيذ الكود السابق سوف نشاهد أن الكائن CommandBuilder كون لنا جملة SQL الخاصة بالحذف بشكل احترافي ، وأن عدد البارامترات التي استخدمها 9 ..
delete FROM Information WHERE ((ID = ?) AND ((? = 1 AND Name IS NULL) OR (Name = ?)) AND ((? = 1 AND Age IS NULL) OR (Age = ?)) AND ((? = 1 AND Phone IS NULL) OR (Phone = ?)) AND ((? = 1 AND Email IS NULL) OR (Email = ?)))
- ويبين الكود التالي كيف يمكن استخدام CommandBuilder لصنع كائن أمر DataAdapter لتحديث بيانات سجل ..
وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديلات الجديدة ، وهي ربط الكائن CommandBuilder بالكائن DataAdapter ، وفي السطر الأخير نعرض MsgBox نعرض فيها جملة SQL التي قام CommandBuilder ببنائها وكذلك عدد البارامترات التي استخدمها ..
Dim selectCommandText As String = "select * FROM Information order by name"
Dim selectConnection As OleDbConnection = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" _
        & "Data Source=|DataDirectory|\Note.mdb;" _
        & "User Id=admin;" _
        & "Jet OLEDB:Database Password=ado.net;")
Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
Dim ds As New DataSetinstance_adapter.Fill(ds, "Information")
ds.Tables(0).Rows(3).Item("Name") = "Yaser AL-Shikh"
ds.Tables(0).Rows(3).Item("Age") = "32"
ds.Tables(0).Rows(3).Item("Phone") = "0123456789"
ds.Tables(0).Rows(3).Item("Email") = "yaser1395@hotmail.com"
Dim MyComB As New OleDbCommandBuilder(instance_adapter)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")
MsgBox("update Successfully...", MsgBoxStyle.Information)
MessageBox.Show(String.Format("The SQL updateCommand Is :{0}{1}{2}{3}{4}The Count Of Paramters Is: {5}", vbNewLine, vbNewLine, MyComB.GetupdateCommand().CommandText, vbNewLine, vbNewLine, MyComB.GetupdateCommand().Parameters.Count))
بعد تنفيذ الكود السابق سوف نشاهد أن الكائن CommandBuilder كون لنا جملة SQL الخاصة بتحديث بيانات سجل بشكل احترافي ، وأن عدد البارامترات التي استخدمها 13 ..

update Information SET Name = ?, Age = ?, Phone = ?, Email = ? WHERE ((ID = ?) AND ((? = 1 AND Name IS NULL) OR (Name = ?)) AND ((? = 1 AND Age IS NULL) OR (Age = ?)) AND ((? = 1 AND Phone IS NULL) OR (Phone = ?)) AND ((? = 1 AND Email IS NULL) OR (Email = ?)))


وقبل أن نختم الحديث عن CommandBuilder أريد أن أوضح شيء مهم جداً ، وهو أنه قد يحدث عند تعبئتك للكائن DataSet بالجدول من خلال استخدام جملة SQL ( select ) ، تكون هذه الجملة قد احتوت على استخدام الأقواس ( ] [ ) أو على فراغات في تسمية الجدول أو الحقول ، أو أن ألجملة تحتوي على كلمات محجوزة للغة SQL في تسمية الحقول مثل MEMO و DATE ، في هذه الحالة يجب علينا إضافة القوسين ( [ ] ) لجمل SQL ( insertCommand ، updateCommand ، deleteCommand )التي ينشئها باني الأوامر ، ويتم ذلك من خلال الخاصيتان QuotePrefix و QuoteSuffix ، وطرقة عملها سهل جداً ، والكود التالي يوضح الطريقة الصحيحة للتحديث من خلال باني الأوامر في مثل هذه الحالات ..
Dim MyComB As New OleDbCommandBuilder(instance_adapter)
MyComB.QuotePrefix = "["
MyComB.QuoteSuffix = "]"
instance_adapter.insertCommand = MyComB.GetinsertCommand
instance_adapter.updateCommand = MyComB.GetupdateCommand
instance_adapter.deleteCommand = MyComB.GetdeleteCommand
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.update(ds, "Information")


حررت من قبل: vb2005 في السبت,09/جمادى الثانية/1431 هـ,03:54 مساءً


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالأربعاء,13/جمادى الثانية/1431 هـ,05:05 مساءً
المشاركة #8

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519



ربط عناصر التحكم Binding Controls :-
مقدمة : تقوم فكرة ربط عناصر التحكم على ربط البيانات المتوفرة في DataTable أو DataSet بأحد عناصر التحكم الموجودة في واجهة المستخدم الرسومية على سبيل المثال :
CheckBox ، ComboBox ، DateTimePicker ، Label ، LinkLabel ، ListBox ،
ListView ، MonthCalendar ، PictureBox ، ProgressBar ، RadioButton ،
RichTextBox ، StatusBar ، TextBox ، TreeView ، DataGridView ...
هذا فقط على سبيل المثال لا الحصر ، وبعد أن يتم ربط عناصر التحكم بمصدر البيانات ، فإنه يتم إنعاشها فتصبح تنبض بالحياة ، حيث أن أي تغييرات تتم على مصدر البيانات ستنعكس تلقائياً عليها وكذلك العكس حيث أن أي تغيير يتم على قيم هذه العناصر فإنه ينعكس على مصدر البيانات وفي هذه الحالة لو استدعينا الخاصية HasChanges التابعة للكائن DataSet فإنها سوف تعيد القيمة True . إضافة إلى أن الربط فيما بين عناصر التحكم ومصادر البيانات يسهل علينا عملية البحث و الإبحار والتنقل بين البيانات لان عناصر التحكم في هذا الحالة سوف تعرض القيم الحالية للبيانات المتوفرة في مصادر البيانات .
طرق ربط البيانات بعناصر التحكم :-
هناك طريقتان لربط البيانات بعناصر التحكم ، أولاهما Binding at design time أي الربط في وقت التصميم ويتم باستخدام الأدوات والمعالجات ، والأخرى Binding at run time أي الربط في وقت التشغيل ويتم باستخدام الكود وهو ما سنقوم بدراسته هنا .
أنواع ربط البيانات بعناصر التحكم :-
هناك نوعان من الربط ويعتمدان على نوع عنصر التحكم الذي نريد أن نربطه بمصدر البيانات ..
* النوع الأول ويسمى الربط البسيط ( Simple-bind control ) :-
وهو يختص بعناصر التحكم التي تستقبل ( single value ) أي قيمة حقل واحد من مصدر البيانات على سبيل المثال TextBox ، Lable ، DateTimePicker ، PictureBox ، MonthCalendar
وللقيام بعملية الربط سوف نستخدم الكائن Binding ، ونقوم بتجهيزه للعمل وذلك عن طريق تزويده ببعض المتغيرات ( البارامترات ) وهي كالتالي :
1- PropertyName :
( The name of the control property to bind )
وهو يشير إلى الخاصية الخاصة بأداة التحكم والتي سوف تستورد القيمة النصية القادمة من قاعدة البيانات وتعرضها في النموذج ، ومن خلالها أيضا نقوم بتصدير القيمة المخزنة فيها إلى قاعدة البيانات وذلك عند عملية التحديث . وهي تختلف من أداة تحكم إلى أداة أخرى ، فهي يمكن أن تأخذ إحدى القيم التالية ((Text ، Tag ، Value ، Checked ، Image ، selectedValue )) .
2- DataSource :
( An Object that represents the data source )
وهو يشير إلى مصدر البيانات ، ونقصد بمصدر البيانات هنا الكائن الذي يحتوي على جدول أو جداول قاعدة البيانات ، ونستطيع أن نحدد على سبيل المثال أي كائن من الكائنات التالية كمصدر بيانات (( DataSet ، DataTable ، DataView ، DataViewManager ، BindingSource ))
3- DataMember :
(The property or list to bind to )
وهو يشير إلى قيمة نصية تحمل اسم العمود الموجود في جدول قاعدة البيانات والذي نريد أن نعرض بيانات حقوله في أداة التحكم .
4- formattingEnabled :
( true to format the displayed data; otherwise, false )
وهو متغير اختياري ، له قيمتان إما صائب True يسمح بقراءة القيمة المخزنة وتهيئها وتحويلها من صيغة إلى صيغة أخرى أو خاطئ False وهو عكس السابق ، وهو مهم جدا لبعض الأدوات أعلم منها PictureBox حيث يجب أن نجعله True من أجل تحويل القيمة المخزنة في قاعدة البيانات من byte إلى Bitmap كي تتمكن هذه الأداة من عرض الصور ( اجتهاد فردي مني ، والله أعلم ) .
وبعد تجهيز الكائن Binding نقوم بإضافته للخاصية DataBindings التابعة لأداة التحكم . وبذلك نكون قد انتهينا من عملية الربط وأصبحت أداة التحكم متصلة بمصدر البيانات بشكل مباشر . ولعل المثال التالي يساعد في توضيح ما سبق :
لنفرض أن لدينا كائن DataSet كمصدر بيانات وفيه جدول يحمل اسم Information ويوجد بهذا الجدول عمود يحمل اسم Name ، ونريد أن نربط الخاصية Text التابعة لأداة التحكم TextBox بقيم حقول العمود Name ، كي يتم ذلك فلنلقي نظرة على الكود التالي ..
Dim bindName As Binding
bindName = New Binding("Text", MyDataSet.Tables("information"), "Name")
TextBox.DataBindings.Add(bindName)

يمكننا كتابة الكود السابق بالشكل التالي ..
Dim bindName As Binding
bindName = New Binding("Text", MyDataSet, "information.Name")TextBox.DataBindings.Add(bindName)

ويكن اختصار الكود السابق بالشكل التالي ..
Dim bindName As New Binding("Text", MyDataSet, "information.Name")TextBox.DataBindings.Add(bindName)

ويكن اختصار الكود السابق بالشكل التالي ..
TextBox.DataBindings.Add(New Binding("Text", MyDataSet, "information.Name"))

بعد ذلك سوف نجد أن أداة التحكم تعرض لنا قيمه أول حقل من حقول العمود Name ، وعند القيام بالتنقل بين حقول العمود Name والإبحار وكذلك البحث ، سنجد أن القيمة النصية المخزنة في أداة التحكم TextBox تتغير بتغير مواضع تلك الحقول .
وهذه بعض الصور لعمليات الربط البسيط لبعض أدوات التحكم :
TextBox.DataBindings.Add(New Binding("Text", MyDataSet, "information.Name"))TextBox.DataBindings.Add(New Binding("Tag", MyDataSet, "information.Name"))Lable.DataBindings.Add(New Binding("Text", MyDataSet, "information.ID_Student"))
CheckBox.DataBindings.Add(New Binding("Checked", MyDataSet, "information.Good"))
CheckBox.DataBindings.Add(New Binding("Tag", MyDataSet.Tables("information"), "Good")
DateTimePicker1.DataBindings.Add(New Binding("Text", MyDataSet, "information.date"))
DateTimePicker1.DataBindings.Add(New Binding("Value", MyDataSet, "information.date"))
PictureBox.DataBindings.Add(New Binding("Image", MyDataSet, "imageData", True))

* النوع الثاني ويسمى الربط المركب ( Complex-bind control ) :
وهو يختص بعناصر التحكم التي تستقبل ( multiple values ) أي عدة قيم ( DataColumn ) من مصدر البيانات مثل ComboBox ، ListBox أو مصدر بيانات كامل ( DataTable ) مثال DataGridView . وللقيام بعملية الربط هناك أكثر من أسلوب وبعضها مختصر ورائع ، وسوف نتدرج في الشرح إلى أن نصل للأسلوب الأفضل والأسهل . ومن الجدير بالذكر أننا في الربط المركب نستطيع أن نربط أدوات التحكم إما لعرض البيانات فقط أو للعرض والتحديث ، وسنتناول الطريقتين في السطور القادمة .
يجب في البداية تجهيز بعض خصائص أداة التحكم ، وهي تختلف من أداة تحكم إلى أداة تحكم أخرى ، وهي كما يلي :

1- الخاصية DataSource :
ونقوم بتمرير مصدر البيانات لهذه الخاصية ، ونقصد بمصدر البيانات هنا الكائن الذي يحتوي على جدول قاعدة البيانات والذي نريد أن نعرض بياناته على هذه الأداة ، ونستطيع أن نحدد على سبيل المثال أي كائن من الكائنات التالية كمصدر بيانات لهذه الخاصية (( DataSet ، DataTable ، DataView ، DataViewManager ، BindingSource ))

2- DisplayMember :ونقوم بتمرير قيمة نصية لهذه الخاصية تحمل اسم العمود الموجود في جدول قاعدة البيانات والذي نريد أن نعرض بيانات حقوله في أداة التحكم .

3- ValueMember ( اختياري ) :
وتظهر أهمية هذه الخاصية في حالة كنا نريد أن نعرض للمستخدم قيمة أحد الأعمدة ( وذلك باستخدام الخاصية " DisplayMember " التي تحدثنا عنها منذ قليل ) ونخزن في قاعدة البيانات قيمة عمود أخر ، حيث أننا سوف نقوم بتمرير قيمة نصية لهذه الخاصية تحمل اسم العمود الأخر .

4- DataBindings ( اختياري ):
وتظهر أهمية هذه الخاصية في حالة كنا نريد أن نحفظ في قاعدة البيانات القيمة التي تعرضها أداة التحكم أو القيمة المخزنة في الخاصية ValueMember والتي تحدثنا عنها منذ قليل ، ولتجهيز هذه الخاصية سوف نتبع نفس الأسلوب الذي اتبعناه في الربط البسيط والذي تحدثنا عنه بالتفصيل فيما سبق .

أمثلة تطبيقية على الربط المركب لأدوات التحكم ( Complex-bind control ) :

1- بفرض أننا نريد أن نربط أداة تحكم من نوع ListBox بقيم العمود الذي يحمل اسم " Name " وهو أسماء الطلاب ، علما أن هذا العمود أحد أعمدة الجدول Students وهذا الجدول مخزن في الكائن DataSet ، وللقيام بعملية الربط فلنتفحص الكود التالي ..
ListBox1.DataSource = MyDataSetListBox1.DisplayMember = "Students.name"

ويمكن كتابة الكود السابق بشكل آخر ..
ListBox1.DataSource = MyDataSet.Tables("Students")ListBox1.DisplayMember = "name"


2- بفرض أننا نريد أن نملأ أداة التحكم من نوع ComboBox بالقيم ( Male , Female ) وذلك بالطريقة التقليدية ، ولكنا أيضا نريد أن نجهز الأداة نفسها كي تكون قادرة على حفظ القيمة التي يختارها المستخدم من القائمة المنسدلة لها في العمود الذي يحمل اسم " CustomerSex " علما أن هذا العمود أحد أعمدة الجدول Customers وهذا الجدول مخزن في الكائن DataSet ، وللقيام بعملية الربط و التجهيز للحفظ فلنتفحص الكود التالي ..
ComboBox1.Items.Add("Male")
ComboBox1.Items.Add("Female")
ComboBox1.DataBindings.Add(New Binding("Text", MyDataSet.Tables("Customers"), "CustomerSex"))

3- بفرض أننا نريد أن نربط أداة تحكم من نوع ComboBox بقيم العمود الذي يحمل اسم " City " وهو أسماء المدن ، علما أن هذا العمود أحد أعمدة الجدول Information وهذا الجدول مخزن في الكائن DataSet ، ونريد أيضا أن نجهز نفس الأداة كي تكون قادرة على حفظ القيمة التي يختارها المستخدم من القائمة المنسدلة لها في العمود الذي يحمل اسم " CustomerCity " علما أن هذا العمود أحد أعمدة الجدول CustomerAddresses وهذا الجدول مخزن في الكائن DataSet أيضاً ، وللقيام بعملية الربط و التجهيز للحفظ فلنتفحص الكود التالي ..
ComboBox1.DataSource = MyDataSet.Tables("Information")ComboBox1.DisplayMember = "City"
ComboBox1.DataBindings.Add(New Binding("text", MyDataSet.Tables("CustomerAddresses"), " CustomerCity"))


4- بفرض أننا نريد أن نربط أداة تحكم من نوع ComboBox بقيم العمود الذي يحمل اسم " City " وهو أسماء المدن وذلك من أجل عرض أسماء المدن للمستخدم ، و نريد من الأداة نفسها أن تحتفظ بقيم العمود الذي يحمل اسم " ID_City " وهو يدل على أرقام المدن وذلك من أجل عملية الحفظ فيما بعد ، علما أن هذين العمودين من أعمدة الجدول Information وهذا الجدول مخزن في الكائن DataSet ، ونريد أيضا أن نجهز نفس الأداة كي تكون قادرة على حفظ القيمة التي تحتفظ بها وليس التي تعرض للمستخدم والتي يختارها المستخدم من القائمة المنسدلة لها ، في العمود الذي يحمل اسم " CustomerCity " علما أن هذا العمود أحد أعمدة الجدول CustomerAddresses وهذا الجدول مخزن في الكائن DataSet أيضاً ، وللقيام بعملية الربط و التجهيز للحفظ فلنتفحص الكود التالي ..
ComboBox1.DataSource = MyDataSet.Tables("Information")ComboBox1.DisplayMember = "City"
ComboBox1.ValueMember = "ID_City"
ComboBox1.DataBindings.Add(New Binding("selectedValue", MyDataSet.Tables("CustomerAddresses"), " CustomerCity"))


5- بفرض أننا نريد أن نربط مصدر بيانات كامل مثل الجدول CustomerAddresses ( هذا الجدول مخزن في الكائن DataSet ) في أداة التحكم DataGridView وذلك من أجل عرض البيانات وحتى التعديل عليها وحفظها فيما بعد ، فإن الأمر بغاية السهولة ، وللقيام بعملية الربط و التجهيز للحفظ فلنتفحص الكود التالي ..
DataGridView1.DataSource = MyDataSet
DataGridView1.DataMember = "CustomerAddresses"

ويمكن اختصار الكود كي يصبح بالشكل التالي ..
DataGridView1.DataSource = MyDataSet.Tables("CustomerAddresses")


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

ملاحظة : موضوعنا القادم سوف يكون " الكائن BindingSource " ، وسوف نتعلم كيف يمكننا إدارة العمل على الكائن Dataset من إضافه وحذف وغيره ، وكذلك الإبحار في قاعدة البيانات وعمل فلتر الترشيح للبيانات .. إلى أن نلتقي مرة أخرى أترككم في حفظ الله ورعايته .. ياسر الشيخ


((سبحانك اللهم وبحمدك، أشهد أن لا إله إلا أنت، أستغفرك وأتوب إليك ))


حررت من قبل: vb2005 في الأربعاء,13/جمادى الثانية/1431 هـ,05:44 مساءً


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالجمعة,15/جمادى الثانية/1431 هـ,12:28 صباحاً
المشاركة #9

الرتبة في المنتدى:نقيب

أيقونة المجموعة

المجموعة: أعضاء فعالين
المشاركات: 303
سجل في:الخميس,04/ذو القعدة/1430 هـ,02:27 صباحاً
الدولة:مصر
رقم العضوية: 92519




اليوم عملت البرنامج الاول لشرح الوضع المنفصل وهو
ربط datagridview بجدول


حررت من قبل: vb2005 في الجمعة,15/جمادى الثانية/1431 هـ,12:36 صباحاً



الملفات المرفقة
 بجدول datagridview ربط.rar ( 63.19ك ) عدد مرات التنزيل: 2304


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة
مشاركةالجمعة,15/جمادى الثانية/1431 هـ,10:07 مساءً
المشاركة #10

الرتبة في المنتدى:رقيب

أيقونة المجموعة

المجموعة: الأعضاء
المشاركات: 31
سجل في:الأربعاء,23/جمادى الأولى/1426 هـ,06:50 مساءً
الدولة:السعودية
رقم العضوية: 3920



بارك الله فيك


--------------------
للأعلىأبلغ المشرف عن هذه المشاركة
لتعقيب على هذه المشاركة مباشرة

    

عدد المتصفحين لهذا المنتدى «1»: (الضيوف «1» - المتخفون «0»)
الأعضاء «0»: .

عدد الصفحات : 2  1  2   > » موضوع مغلق إضافة موضوع جديد



 
الوقت الأن:اليوم,02:16 مساءً بتوقيت القدس المحتلة

Powered By arabmoheet v3.1

منتديات المحيط العربي  -  راسلنا  -   أعلى
X   رسالة المنتدى
(سوف يتم اغلاق هذه النافذة بعد 2 ثانية)
X   رسالة المنتدى
(سوف يتم اغلاق هذه النافذة بعد 2 ثانية)