بسم الله الرحمن الرحيم
وبه أبدا وأستعين ، وأختم بالصلاة والسلام على خاتم الأنبياء والمرسلين نبينا محمد وعلى آله وصحبه أجمعين ، أما بعد ..
=============
لقد تأخرت عنكم كثيراً ، لذلك أريد أن أعتذر للجميع ، وها نحن هنا من جديد ..
=============
الخاصية 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 لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
1 Dim selectCommandText As String = "SELECT * FROM Information;"
2 Dim selectConnection As OleDbConnection = New OleDbConnection _
3 ("Provider=Microsoft.Jet.OLEDB.4.0;" _
4 & "Data Source=|DataDirectory|\Note.mdb;" _
5 & "User Id=admin;" _
6 & "Jet OLEDB:Database Password=ado.net;")
7 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
8 Dim ds As New DataSet
9 instance_adapter.Fill(ds, "Information")
10 Dim MyDR As DataRow = ds.Tables("Information").NewRow
11 MyDR.Item("Name") = "Yaser Mohamed"
12 MyDR.Item("Age") = "32"
13 MyDR.Item("Phone") = "0123456789"
14 MyDR.Item("Email") = "Yaser1395@hotmail.com"
15 ds.Tables("Information").Rows.Add(MyDR)
16 Dim InsertCommand As New OleDbCommand
17 InsertCommand.Connection = selectConnection
18 InsertCommand.CommandText = "INSERT INTO Information ([Name],[age],[phone],[email]) VALUES (?,?,?,?)"
19 InsertCommand.CommandType = CommandType.Text
20 InsertCommand = InsertCommand
21 InsertCommand.Parameters.AddWithValue("?", "Yaser Mohamed")
22 InsertCommand.Parameters.AddWithValue("?", "32")
23 InsertCommand.Parameters.AddWithValue("?", "0123456789")
24 InsertCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
25 instance_adapter.InsertCommand = InsertCommand
26 Me.BindingContext(ds, "Information").EndCurrentEdit()
27 instance_adapter.Update(ds, "Information")
28 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- مربع رسالة تخبرنا بنجاح العملية .
ويكمن كتابة الكود السابق بشكل أخر وسوف يؤدي نفس النتيجة ، فلنتأمل الكود التالي ..
1 Dim selectCommandText As String = "SELECT * FROM Information;"
2 Dim selectConnection As OleDbConnection = New OleDbConnection _
3 ("Provider=Microsoft.Jet.OLEDB.4.0;" _
4 & "Data Source=|DataDirectory|\Note.mdb;" _
5 & "User Id=admin;" _
6 & "Jet OLEDB:Database Password=ado.net;")
7 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
8 Dim ds As New DataSet
9 instance_adapter.Fill(ds, "Information")
10 Dim MyDR As DataRow = ds.Tables("Information").NewRow
11 MyDR.Item("Name") = "Yaser Mohamed"
12 MyDR.Item("Age") = "32"
13 MyDR.Item("Phone") = "0123456789"
14 MyDR.Item("Email") = "Yaser1395@hotmail.com"
15 ds.Tables("Information").Rows.Add(MyDR)
16 instance_adapter.InsertCommand = New OleDbCommand("INSERT INTO Information ([Name],[age],[phone],[email]) VALUES (?,?,?,?)" , selectConnection)
17 instance_adapter.InsertCommand.Parameters.Clear()
18 instance_adapter.InsertCommand.Parameters.AddWithValue("?", "Yaser Mohamed")
19 instance_adapter.InsertCommand.Parameters.AddWithValue("?", "32")
20 instance_adapter.InsertCommand.Parameters.AddWithValue("?", "0123456789")
21 instance_adapter.InsertCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
22 Me.BindingContext(ds, "Information").EndCurrentEdit()
33 instance_adapter.Update(ds, "Information")
24 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 لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
1 Dim selectCommandText As String = "SELECT * FROM Information order by name"
2 Dim selectConnection As OleDbConnection = New OleDbConnection _
3 ("Provider=Microsoft.Jet.OLEDB.4.0;" _
4 & "Data Source=|DataDirectory|\Note.mdb;" _
5 & "User Id=admin;" _
6 & "Jet OLEDB:Database Password=ado.net;")
7 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
8 Dim ds As New DataSet
9 instance_adapter.Fill(ds, "Information")
10 Dim MYPosition As String = Me.BindingContext(ds, "Information").Position
11 Dim IdValue As String = ds.Tables("Information").Rows(MYPosition).Item("ID")
12 Me.BindingContext(ds, "Information").RemoveAt(MyPosition)
13 instance_adapter.DeleteCommand = New OleDbCommand("DELETE FROM Information WHERE Information.ID=?;", selectConnection)
14 instance_adapter.DeleteCommand.Parameters.Clear()
15 instance_adapter.DeleteCommand.Parameters.AddWithValue("?",IdValue)
16 Me.BindingContext(ds, "Information").EndCurrentEdit()
17 instance_adapter.Update(ds, "Information")
18 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 لتولي مسؤلية عملية النسخ ، فلنلقي نظرة متفحصة على الكود ..
1 Dim selectCommandText As String = "SELECT * FROM Information"
2 Dim selectConnection As OleDbConnection = New OleDbConnection _
3 ("Provider=Microsoft.Jet.OLEDB.4.0;" _
4 & "Data Source=|DataDirectory|\Note.mdb;" _
5 & "User Id=admin;" _
6 & "Jet OLEDB:Database Password=ado.net;")
7 Dim instance_adapter As New OleDbDataAdapter(selectCommandText, selectConnection)
8 Dim ds As New DataSet
9 instance_adapter.Fill(ds, "Information")
10 Dim MyPosition As Integer = Me.BindingContext(ds, "Information").Position
11 Dim IdValue As String = ds.Tables(0).Rows(MyPosition).Item("ID")
12 ds.Tables(0).Rows(MyPosition).Item("Name") = "Yaser AL-Shikh"
13 ds.Tables(0).Rows(MyPosition).Item("Age") = "32"
14 ds.Tables(0).Rows(MyPosition).Item("Phone") = "123456789"
15 ds.Tables(0).Rows(MyPosition).Item("Email") = "Yaser1395@hotmail.com"
16 instance_adapter.UpdateCommand = New OleDbCommand("UPDATE Information set Name=?, Age=?, Phone=?, Email=? WHERE Id =?", selectConnection)
17 instance_adapter.UpdateCommand.Parameters.Clear()
18 instance_adapter.UpdateCommand.Parameters.AddWithValue("?", "Yaser AL-Shikh")
19 instance_adapter.UpdateCommand.Parameters.AddWithValue("?", "25")
20 instance_adapter.UpdateCommand.Parameters.AddWithValue("?", "123456789")
21 instance_adapter.UpdateCommand.Parameters.AddWithValue("?", "Yaser1395@hotmail.com")
22 instance_adapter.UpdateCommand.Parameters.AddWithValue("?", IdValue)
23 Me.BindingContext(ds, "Information").EndCurrentEdit()
24 instance_adapter.Update(ds.Tables("Information"))
25 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 لعله يوجد من يستفيد منها أو يوضحها لنا ، ونصها الأساسي هو :
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 ، وسوف نتعلم كيف يختصر لنا هذا الكائن الكثير من الأكواد السابقه ، كما سنشاهد كيف يقوم هذا الكائن ببناء الأوامر الخصة بالتحديث .. إلى أن نلتقي مرة أخرى أترككم في حفظ الله ورعايته .. ياسر الشيخ
((سبحانك اللهم وبحمدك، أشهد أن لا إله إلا أنت، أستغفرك وأتوب إليك ))
1 - سقوط الإنسان ليس فشلاً ، ولكن الفشل أن يبقى حيث سقط .
2 - الفاشلون قسمان : قسم فكر ولم يفعل ، وقسم فعل ولم يفكر .
-------------------------------------------------------
درس في ADO.NET 2005, التعامل مع الجداول المترابطة في ado.net 2005
