Professional Documents
Culture Documents
.
كود
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\ MymdbFile.mdb;User
;ID=Admin;Jet OLEDB:Database Password=You'rePassword
مثال : 2
سلسة اتصال بملف قاعدة بيانات برنامج .. SQL Server
كود
Provider=SQLOLEDB;Data Source=SQL Server DB;Initial
Catalog=Northwind;User ID=You'reUserName;Password=You'rePassword
ي طريقة
بعد التعرف على سلسلة االتصال يجب أن نتعرف على نوع ّ
االتصال بقاعدة البيانات ..
ي طريقة االتصال بقواعد البيانات :
* نوع ّ
من الجدير بالذكر أننا لو أردنا أن نتصل على قاعدة البيانات بواسطة
ADO.NETيجب أن نختار طريقة االتصال المناسبة الحتياجاتنا ،فلدينا
طرقتين لالتصال وهما االتصال المتصل ( ) Connection Orientedو االتصال
المنفصل ( . ) Connectionless Orientedولكل منهما امتيازاته وعيوبه و
إستراتجياته الخاصة به في العمل ،غير أن األخير يعتبر األمثل في التعامل
مع قواعد البيانات ،وهنا بالتحديد يضيع أغلب من يرغبون تعلم برمجة
قواعد البيانات من خالل . ADO.NET
-----------------------------------------------------------------------------------
كود
Imports System.Data.OleDb
كود
Imports System.Data. SqlClient
وتندرج تحته مجموعة من الكائنات ولكن ما يهمنا منها كمبتدئين ما يلي :
SqlCommand , SqlConnection , SqlDataAdapter , SqlDataReader ,
SqlParameter , SqlCommandBuilder , SqlTransaction.
. SqlException
بعد تجهيز الخصائص السابقة لكائن األمر ونريد تنفذ األعمال المطلوبة منه
عند حصوله على تيار من البيانات ،لدينا ثالثة طرق يتم بها العمل :
: Read -ومهمتها هي توجه قارئ البيانات إلى قراءة الصف األول من
النتائج ،وترجع القيمة Trueإذا وجد صف أو Falseإذا لم يوجد صف .
: Item -ومهمتها هي استرجاع قيمة العمود إما باستخدام أسم العمود أو
رقمه .
: isDBnull -ومهمتها هي اختبار فيما إذا كانت البيانات تحتوي على قيم
. Null
: Close -ومهمته هي إغالق كائن قارئ البيانات وال يقوم بإغالق االتصال .
مع مالحظة أنه يجب دائماً إغالق قارئ البيانات عند االنتهاء منه الن كائن
األوامر إذا كان يحتوي على معامالت إخراج أو قيم جديدة لن يكون في
اإلمكان التعامل معها إلى أن يتم االنتهاء من إغالق كائن . DataReader
سوف نركز في الجانب العملي على الثالثة طرق التي يتم بها العمل في
كائن األوامر OleDbCommandوالذي قلنا فيما سبق أنه يمثل القلب .
ثانياً :استدعاء فضاء األسماء الخاص بمزود بيانات برنامج Microsoft Office
، Accessوذلك بكتابة الكود التالي في أعلى صفحة الكود ..
كود
Imports System.Data.OleDb
ثالثاً :
التصريح عن الكائنات التي نحتاجها كمتغيرات في منطقة Declarations
في صفحة الكود وذلك كي يتم التعرف علية في مختلف أجزار النموذج
،في البداية نقوم بتهيئة كائن االتصال وليكن اسمه ، Connكما في الكود
التالي ...
كود
Dim Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\ ConnectedMode\Note.mdb;User ID=Admin;Jet OLEDB:Database
)"Password=ado.net
ولكي ال نجعل برنامجنا الذي نتدرب علية مقيد بمسار ثابت وهو " \C:
" ConnectedMode\MyNote.mdbنستطيع أن نجعله أكثر مرونة بحيث
يعمل على أي مسار شرط أن يتواجد ملف قاعدة البيانات والملف التنفيذي
للبرنامج في نفس الموقع ،وذلك من خالل العبارة التالية "|
"|DataDirectoryبحيث يصبح الكود السابق كما يلي ..
كود
Dim Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=|DataDirectory|Note.mdb;User ID=Admin;Jet OLEDB:Database
)"Password=ado.net
كود
Dim MyCmd As New OleDbCommand
كود
Dim MyReader As OleDbDataReader
رابعاً :في حدث تحميل النموذج نقوم بفتح االتصال ..
كود
Conn .Open
خامساً :نقوم بتهيئة كائن األمر ( باستخدام جملة استعالم بنيوية تقوم
بتحديد حقول معينة من الجدول الموجود في قاعدة البيانات ) كما ذكرنا
في الجزء ألنضري من الدرس ،وذلك من خالل الكود التالي ..
كود
MyCmd.Connection = Conn
MyCmd.CommandType = CommandType.Text
MyCmd.CommandText = "SELECT ID, Name, Phone FROM Information ORDER BY
";Name
كود
MyReader = MyCmd.ExecuteReader
سابعاً :قبل إسناد قيم الحقول إلى مربعات النص نتحقق من أن كائن
القراءة وجد صفوف تحتوي على بيانات من خالل أداة الشرط IF .. Then ..
Else .. End Ifوباستخدام الخاصية ، Readوفي حالة توفر البيانات نقوم
بإسناد قيمة كل حقل لمربع النص الخاص به من خالل الخاصية ، Item
كما في الكود التالي ..
كود
If MyReader.Read Then
)" txtID.Text = MyReader.Item("ID
)" txtName.Text = MyReader.Item("Name
)" txtPhone.Text = MyReader.Item("Phone
Else
) MsgBox(" Empty ", MsgBoxStyle.Exclamation
End If
ثامناً :إغالق كال ً من كائن القراءة وكائن االتصال ،كما في الكود التالي ...
كود
)(MyReader.Close
)(Conn.Close
كود
Conn .Open
كود
Dim InsertCommand As New OleDbCommand
InsertCommand.Connection = Conn
InsertCommand.CommandType = CommandType.Text
)InsertCommand.CommandText = "INSERT INTO Information(Name,Phone
";)?VALUES(?,
مالحظة :لم نضيف أي قيمة للحقل IDألنه له خاصية الترقيم التلقائي .
كود
)(InsertCommand.Parameters.Clear
)InsertCommand.Parameters.AddWithValue("?", txtName.Text
)InsertCommand.Parameters.AddWithValue("?", txtPhone.Text
كود
)(InsertCommand.ExecuteNonQuery
كود
)(InsertCommand.Dispose
)(Conn.Close
)MsgBox(" OK ", MsgBoxStyle.Information
ثالثاً :في حدث النقر لـ btnUpdateنقوم بما يلي ..
-1نقوم بفتح االتصال ..
كود
Conn .Open
كود
Dim UpdateCommand As New OleDbCommand
UpdateCommand.Connection = Conn
UpdateCommand.CommandType = CommandType.Text
?=UpdateCommand.CommandText = "UPDATE Information set Name=? , Phone
";?= WHERE Id
كود
)(UpdateCommand.Parameters.Clear
)UpdateCommand.Parameters.AddWithValue("?", txtName.Text
)UpdateCommand.Parameters.AddWithValue("?", txtPhone.Text
)UpdateCommand.Parameters.AddWithValue("?", txtID.Text
كود
)(UpdateCommand.ExecuteNonQuery
كود
)(UpdateCommand.Dispose
)(Conn.Close
)MsgBox(" OK ", MsgBoxStyle.Information
كود
Conn .Open
كود
Dim DeleteCommand As New OleDbCommand
DeleteCommand.Connection = Conn
DeleteCommand.CommandType = CommandType.Text
" ;? = DeleteCommand.CommandText = " DELETE FROM Information WHERE id
كود
)(DeleteCommand.Parameters.Clear
)DeleteCommand.Parameters.AddWithValue("?", txtID.Text
كود
)(DeleteCommand.ExecuteNonQuery
كود
)(DeleteCommand.Dispose
)(Conn.Close
)MsgBox(" OK ", MsgBoxStyle.Information
مثال : 3الطريقة ، ExecuteScalarاستنادا للمثال األول ماذا لو أردنا
معرفة عدد السجالت المخزنة في الجدول ، Informationإذا فلنتابع شرح
هذا المثال ..
أوال ً :نضيف ، Buttonونسميه . btnCountId
ثانياً :في حدث النقر لـ btnCountIdنقوم بما يلي ..
-1نقوم بفتح االتصال بقاعدة البيانات ..
كود
)(Conn.Open
كود
Dim CountIdCommand As New OleDbCommand
CountIdCommand.Connection = Conn
CountIdCommand.CommandType = CommandType.Text
CountIdCommand.CommandText = "SELECT Count(id) AS CountID FROM
";Information
كود
)(Dim CountId As String = CountIdCommand.ExecuteScalar
كود
)MsgBox(CountId, MsgBoxStyle.Information
كود
)(InsertCommand.Dispose
)(Conn.Close
)MsgBox(" OK ", MsgBoxStyle.Information
كود
Dim MyTransaction As OleDbTransaction
كود
MyTransaction = Conn.BeginTransaction
كود
InsertCommand.Transaction = MyTransaction
كود
)(MyTransaction.Commit
وفي حالة وجود أي مشكلة نستدعي الخاصية Rollbackالتابعة للكائن
Transactionوذلك للقيام بإلغاء العملية ...
كود
)( MyTransaction.Rollback
لذلك ننصح تعشيش كل العمليات التي يتوقع وجود مشاكل بها داخل دالة
اكتشاف األخطاء . Try...Catch…Finally
كود
Dim MyTransaction As OleDbTransaction
Dim UpdateCommand As New OleDbCommand
كود
Try
العمليات التي نرغب في اصطياد أخطائها إن وجدت '
Catch Filed As OleDbException
األخطاء التي تم اصطيادها ،باإلضافة للتصحيح المناسب لها '
Finally
العمليات التي يجب تنفيذها على كل حال '
End Try
مالحظة :في الجزء الذي يحتوي على العمليات التي نرغب في اصطياد
أخطائها إن وجدت من دالة Tryنقوم بما يلي ..
.. نقوم بفتح االتصال-3
كود
Conn .Open
استنادا لما تعلمناه في السطور السابقة نقوم بإعداد وتجهيز كال ً من-4
( مع مالحظة أننا استخدمنا هذهCommand والكائنTransaction الكائن
لوحده ثمName لتحديث الحقلExecuteNonQuery المرة الخاصية
مع تعمد كتابة خطأ في، Phone استخدمناها مر ًة أخرى لتحديث الحقل
" وبالتحديد في الكلمةPhone جملة االستعالم التي نحدث بها الحقل
وذلك حتى نتعرف على الطريقة، ""ABDATE " والتي كتبناهاUPDATE
... ) التي سوف يتم بها اصطياد الخطأ وكيف سوف يتم تصحيحه
كود
MyTransaction = Conn.BeginTransaction
UpdateCommand.Connection = Conn
UpdateCommand.Transaction = MyTransaction
UpdateCommand.CommandType = CommandType.Text
UpdateCommand.CommandText = "UPDATE Information set Name=? WHERE Id
=?;"
UpdateCommand.Parameters.Clear()
UpdateCommand.Parameters.AddWithValue("?", txtName.Text)
UpdateCommand.Parameters.AddWithValue("?", txtID.Text)
UpdateCommand.ExecuteNonQuery()
UpdateCommand.CommandText = "ABDATE Information set Phone=? WHERE Id
=?;"
UpdateCommand.Parameters.Clear()
UpdateCommand.Parameters.AddWithValue("?", txtPhone.Text)
UpdateCommand.Parameters.AddWithValue("?", txtID.Text)
UpdateCommand.ExecuteNonQuery()
كود
MyTransaction.Commit()
MsgBox(" OK ", MsgBoxStyle.Information)
كود
)(MyTransaction.Rollback
)MsgBox(Filed.Message, MsgBoxStyle.Exclamation
كود
)(UpdateCommand.Dispose
)(Conn.Close
مالحظة :لقد استفدت كثيراً في شرح هذا الكائن من درس قدمه األخ
koaoلذلك أحب أن أشكره على ذلك .
** هنا ينتهي حديثنا اليوم ،ونأخذ قسطاً من الراحة ،لكي نستوعب هذه
الجرعة من المعلومات ونصحح أخطائها إن وجدت ،ونعلق على الغير
مفهوم منها ،و نكمل فيما بعد شرح ما تبقى من الدرس وذلك في
المشاركات القادمة ..
مالحظة :موضوعنا القادم يعد متعة برمجة قواعد البيانات الحقيقية ،وهو
االتصال المنفصل ( ، ) Connectionless Orientedوالذي كما أسلفنا يعتبر
األمثل في التعامل مع قواعد البيانات ،ويغنينا عما سواه .إال أننا كان ال بد
لنا من تعلم كيفية التعامل مع االتصال المتصل () Connection Oriented
ألنه يحل لنا بعض اإلشكاالت البرمجية في بعض البرامج ،رغم إننا لم
نتناول كل جوانبه ،ولكني أحب أن يعلم الجميع أنني أفرغت كل ما
بجعبتي من معلومات عنه ،ومن يملك المزيد فليكسب أجرنا ويعلمنا مما
علمه هللا ،
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))
أمثلة الجزأ الثاني من الدرس توجد في الملف المرفق ..
وهناك أيضاً كائنات أخرى ليست فرعية ولكنها خدمية إن صح التعبير ،على
سبيل المثال " DataTable ، DataRow ، DataColumn ، DataRelation ،
OleDbCommandBuilder ، BindingManagerBase ، CurrencyManager
، " ، BindingSource
* الخاصية : Clear
تزيل هذه الخاصية كل البيانات من جميع جداول ، DataSetبينما تبقي
تعريفات الجداول وأي تقييدات معرفه من قبل ... DataSet
كود
MyDs.Clear
فإذا أردنا إزالة الجداول والتقييدات ،نقوم بإعادة إنشاء DataSetكما في
الكود التالي ..
كود
MyDs = New DataSet
الخاصية : HasChanges
إن DataSetيتتبع فيما إذا كان هناك أي تغييرات قد أجريت على بياناته ،
ويمكن استدعاؤها بكل بساطه من خالل الكود التالي ..
كود
MyDs.HasChanges
وتعيد هذه الخاصية القيمة trueإذا كانت البيانات قد حدثت إما لتغيير أو
إضافة أو حذف ،فإذا حمل برنامج ما بشكل أولي بيانات إلى ، DataSet
فإن البيانات لم تغيّر بعد وستعيد هذه الخاصية عندئذ القيمة Falseوعندما
دث المستخدم أي بيانات للجداول فإن هذه الخاصية سوف تعيد القيمة ح ِّ
ُي َ
. trueوإذا قام المستخدم بحفظ بياناته المحدثة ،فإنها تعيد القيمة False
من جديد ..
فلنتأمل هذا الكود ..
كود
If MyDS.HasChanges = True Then
DataSet .نقوم بكتابة أي إجراء في حالة إذا كان هناك أي تغييرات قد أجريت على الـ '
Else
DataSet .نقوم بكتابة أي إجراء في حالة إذا لم يكن هناك أي تغييرات قد أجريت على الـ '
End If
كود
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
الخاصية : 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أحياناً يحتاج برنامج ما تخزين تغييرات في ترتيب معين ،ليفي بمتطلبات
التقييدات العالئقية لجداول قاعدة البيانات .
ولكي نفهم طريقة هذه الخاصية ،فلنتابع سوياً هذه األمثلة ..
كود
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
كود
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
كود
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
كود
)MyDS.Tables(0
كود
MyDS.Tables("Information").Rows.Count
كود
))MsgBox(MyDS.Tables("Information").Rows(0).Item(0
كما نستطيع أعادة كتابة الكود السابق ،بحيث نحدد فيه عمود محدد ،
بكتابة ما يلي ..
كود
))"MsgBox(MyDS.Tables("Information").Rows(0).Item("Name
كود
"MyDS.Tables("Information").Rows(0).Item("Name")="Yaser
كود
)(MyDS.Tables("Information").Rows(0).Delete
للتراجع عن التغيرات التي قمنا بها من تعديل وحذف ،نقوم بكتابة ما
يلي ..
كود
)(MyDS.Tables("Information").Rows(0).RejectChanges
كود
}" Dim MyData() As String = {"Yaser", "32", "Gizan
)MyDS.Tables("Information").Rows.Add(MyData
كود
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").Position
Me.BindingContext(MyDS, "Information").Position = MyPosition +1
كود
Dim MyPosition As Integer = Me.BindingContext(MyDS, "Information").Position
Me.BindingContext(MyDS, "Information").Position = MyPosition -1
** هنا ينتهي حديثنا اليوم ،فما أصبنا من صواب فمن هللا وتوفيقه ،وما
أصبنا من خطأ فمن أنفسنا والشيطان ،لذلك من وجد أي أخطاء
فليصححها لنا مشكوراً ..
ولنأخذ قسطاً من الراحة ،لكي نستوعب هذه الجرعة من المعلومات
ونصحح أخطائها إن وجدت ،ونعلق على الغير مفهوم منها ،و نكمل فيما
بعد شرح ما تبقى من الدرس ،علماً أن موضوع درسنا القادم إن شاء هللا
هو الكائن .. DataAdapter
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))
.. DataSet
تقوم هذه الخاصية بدمج أو إضافة البيانات إلى الكائن DataSetمن كائنات
أخرى يمكن أن تكون مجمعة البيانات DataSetأو جدول DataTableأو
مد َمج عاد ًة بنية مشابهة
مصفوفة البيانات ، DataRowويملك الكائن ال ُ
للكائن DataSetاألصلية ،كمثال :إذا كان الكائن الجديد هو عبارة عن
DataSetأخرى ،فإنه من الممكن أن يملك الجداول نفسها التي في
DataSetاألولى ( األصلية ) .
كود
Dim MyDS As DataSet
Dim SubSet_DS As DataSet
)MyDS.Merge(dataSet
كود
Dim MyDS As DataSet
Dim MyTable As DataTable
)MyDS.Merge(MyTable
كود
Dim MyDS As DataSet
)(Dim 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
-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 DataSet
ds_subset = MyDS.Clone
الخاصية : Copy
تنسخ هذه الخاصية نفس بنية و بيانات الـ DataSetاألصلية إلى الـ
DataSetالجديدة ،بحيث تمتلك نفس الجداول والتقيدات والبيانات أيضاً ،
وبالتالي فإن Copyمشابهة لـ Cloneولكنها تتضمن البيانات ،وطريقة
استخدامها ..
كود
Dim MyDS As New DataSet
Dim ds_subset As New DataSet
ds_subset = MyDS.Copy
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))
-----------------------------------------------------------------------------------------------------------------
-
وبه أبدا وأستعين ،وأختم بالصالة والسالم على خاتم األنبياء والمرسلين
نبينا محمد وعلى آله وصحبه أجمعين ،أما بعد ..
=============
- 3الكائن : DataAdapter
في الدروس السابقة وضحنا العمل الذي يقوم به هذا الكائن ،حيث قلنا
حينها أنه " بمثابة وسيط بين مجموعة البيانات " " DataSetومصادر
البيانات " ، "Data Sourcesحيث يقوم DataAdapterبعملية فتح االتصال
بقاعدة البيانات و استيراد وتصدير البيانات من و إلى مصدرها األساسي ،
وبعد تخزين البيانات في ، DataSetفإنها تصبح منفصلة عن مصدر
البيانات ،الن الكائن DataAdapterيقوم بشكل تلقائي أيضاً بقطع االتصال
بقاعدة البيانات " ،ولكن هذا ليس كل شيء ،ما زلنا نحتفظ بالجزء
األفضل لدرس اليوم ...
يستخدم هذا الكائن كائنان صديقان تعرفنا عليهما فيما سبق ،وهما :
الكائن OleDbConnectionإلدارة اتصاله بقاعدة البيانات ( من فتح االتصال و
غلق االتصال ) ،و الكائن OleDbCommandإلدارة استعالمات SQLالبنيوية
ولتجهيز هذا. ) التي يجب تنفيذها ( من تحديد أو إضافة أو تعديل أو حذف
فقط على المبرمج أن، الكائن للعمل هناك أكثر من طريقة وجميعها جيده
، والكود التالي يبين كيف يتم إنشاء مالئم بيانات، يختار ما يناسبه منها
وكذلك، إلدارة اتصاله بقاعدة البياناتOleDbConnection واستخدام الكائن
والذي يقومSQL إلدارة استعالمOleDbCommand استخدام الكائن
بتحديد مجموعة من الحقول المتوفرة في إحدى جداول قاعدة البيانات
وكذلك سوف نستخدم إحدى خصائص الكائن، التي تم االتصال بها
، ولكنا لن نزعج أنفسنا بها هناSelectCommand وهيDataAdapter
فقط نحتاج إلى القليل من، وسوف نشرحها بالتفصيل في وقت الحق
.. التركيز لتأمل الكود التالي
كود
' 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;")
كود
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 DataSet
instance_adapter.Fill(MyDs)
MsgBox(MyDs.Tables(0).Rows.Count, MsgBoxStyle.Information)
كود
instance_adapter.Fill(ds, "Demo")
ولكي نتأكد من اسم الجدول الذي قمنا بتخزينه في الـ ، DataSetنكتب
الكود التالي لعرض مربع رسالة تخبرنا باسم الجدول ..
كود
)MsgBox(ds.Tables(0).TableName
كود
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")
كود
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 في البداية يتم إنشاء الكائن
) الذيInfo لتغيير اسم الجدول األول ( وليكن أسمةTableMappings
ويلي ذلك نقوم باستخدام، DataSet يجب أن يستقبل البيانات داخل الـ
لتغيير أسماء بعض الحقول ( علماً أننا سوفColumnMappings الخاصية
) وذلك كي نخبر هذه الخاصية أننا0( بالرمزTable نشير للجدول االفتراضي
Fill وبعد ذلك نستدعي الخاصية،) نريد أن يتم إجراء التعديالت عليه
TableMappings الخاصةDataSetTable ثم نغ ِي ّر القيمة، لتحميل البيانات
( كل ذلك يتم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
كود
)"instance_adapter.FillSchema(ds, SchemaType.Mapped , "Info
كود
)instance_adapter.FillSchema(ds, SchemaType.Source
في هذه الحالة سوف يصبح اسم الجدول داخل الـ DataSetاالسم
االفتراضي . Table
كود
)"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
: InsertCommand األمر-
وDataAdapte أحد خصائص الكائنInsertCommand يعد أمر اإلضافة
والطريقة، عمله األساسي هو إضافة سجل جديد إلى سجالت الجدول
التي يعمل بها مشابهة تماماً لكائن األمر الذي قد تحدثنا عنه في الوضع
حيث أنه في البداية سوف نقوم، والمثال التالي موضح بالشرح، المتصل
و نقوم بتحديث، بالبياناتDataSet ثم نمأل الـ، بتجهيز الكائنات للعمل
بشكلDataSet ثم نقوم بنسخ التغييرات التي طرأت على الـ، بياناته
من خال الكائن، إلى مصدر قاعدة البياناتDataSet عكسي من الكائن
وفي األخير، التابع لهInsertCommand وكائن األمرDataAdapter
فلنلقي نظرة، لتولي مسؤلية عملية النسخ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;")
9 instance_adapter.Fill(ds, "Information")
25 instance_adapter.InsertCommand = InsertCommand
)(26 Me.BindingContext(ds, "Information").EndCurrentEdit
)"27 instance_adapter.Update(ds, "Information
ويكمن كتابة الكود السابق بشكل أخر وسوف يؤدي نفس النتيجة ،
فلنتأمل الكود التالي ..
كود
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;")
9 instance_adapter.Fill(ds, "Information")
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")
شرح الكود السابق مطابق للشرح الذي يسبقه ما عدا بعض االختالفات
: وهي متزامنة مع أرقام األسطر، التي سوف نوضحها هنا
إلى مصدرDataSet ولكي نقوم بتصدير البيانات الجديده من الكائن-16
التابع للكائنInsertCommand البيانات نحتاج إلى اعداد وتجهيز كائن األمر
والخاص بإضافة صف جديد وذلك من خالل إسناد كائن أمرDataAdapter
و كائن االتصال الالزم، الالزمة لعملية اإلضافةSQL جديد وإعداده بجملة
. ًأيضا
بعد ذلك نحتاج إلى إضافة البارامترات التي تم تعشيشها في جملة-17
وذلك نجده في كل من األسطر، مع قيمها المحدثة، السابقة الذكرSQL
. ) 21 إلى17 ( رقم
: DeleteCommand األمر-
وDataAdapte أحد خصائص الكائنDeleteCommand يعد أمر الحذف
والطريقة التي، عمله األساسي هو حذف سجل من سجالت الجدول
يعمل بها مشابهة تماماً لكائن األمر الذي قد تحدثنا عنه في الوضع
والتيSQL في جملةWhere حيث سنحتاج إلى وجود فقرة، المتصل
، تشير إلى بارامتر ( معامل ) يساعدنا في تحديد السجل المطلوب حذفه
حيث أنه في البداية سوف نقوم بتجهيز، والمثال التالي موضح بالشرح
و نقوم بحذف السجل، بالبياناتDataSet ثم نمأل الـ، الكائنات للعمل
( تعتبر عمليه الحذف هذهDataSet الحالي من الجدول المخزن في الكائن
، ) DataSet تحديث للسجالت الموجودة في الجدول المخزن في الكائن
بشكل عكسي منDataSet ثم نقوم بنسخ التغييرات التي طرأت على الـ
وذلك من خال الكائن، إلى مصدر قاعدة البياناتDataSet الكائن
وفي األخير، التابع لهDeleteCommand وكائن األمرDataAdapter
فلنلقي نظرة، لتولي مسؤلية عملية النسخ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;")
12 Me.BindingContext(ds, "Information").RemoveAt(MyPosition)
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")
لذا، شرح الكود السابق ينطبق عليه بعض الشروحات التي سبق ذكرها
: وهو متزامن مع أرقام األسطر، سنكتفي بشرج ما جد من الكود
نقوم بتخزين الرقم الذي يعبّر عن موضع السجل الحالي في الجدول-10
المخزن داخل الكائن ، DataSetوذلك من أجل عملية الحذف من داخل الـ
. DataSet
-11نقوم بتخزين قيمة رقم الحقل المسمى " "IDالخاص بالسجل الحالي
للجدول المخزن داخل الكائن ، DataSetوذلك من أجل عملية الحذف من
مصدر قاعدة البيانات .
-12نقوم هنا باستخدام األمر RemoveAtلحذف السجل الحالي ( والذي
قمنا بتخزين قيمته في المتغير ) MYPositionمن الجدول المخزن في
الكائن DataSetوالذي قمنا بتحديد اسمه ،عندئذ يتم حذف السجل من
داخل الـ DataSetفقط .
-13ولكي نقوم بتصدير البيانات المحدثة من الكائن DataSetإلى مصدر
البيانات نحتاج إلى إعداد وتجهيز كائن األمر DeleteCommandالتابع للكائن
DataAdapterوالخاص بحذف سجل ،وذلك من خالل إسناد كائن أمر
جديد وإعداده بجملة SQLالالزمة لعملية الحذف ،و كائن االتصال الالزم
أيضاً .
-14بعد ذلك نحتاج إلى إضافة البارامتر الذي تم تعشيشه في جملة SQL
السابقة الذكر ،مع قيمته والتي قمنا بتخزينها سابقاً في المتغير
، MyFieldValueوذلك نجده في كل من السطرين رقم ( . ) 15 ، 14
-األمر :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
9 instance_adapter.Fill(ds, "Information")
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"))
لذا، شرح الكود السابق ينطبق عليه بعض الشروحات التي سبق ذكرها
: وهو متزامن مع أرقام األسطر، سنكتفي بشرج ما جد من الكود
Name , Age ,Phone , ( نقوم هنا بتحديث حقول السجل الحالي-12
وذلك نجده في كل، DataSet ) في الجدول المخزن داخل الكائنEmail
) 15 ، 12 ( من السطور رقم
إلى مصدرDataSet ولكي نقوم بتصدير البيانات المحدثة من الكائن-16
التابع للكائنUpdateCommand البيانات نحتاج إلى إعداد وتجهيز كائن األمر
وذلك من خالل إسناد كائن أمر، والخاص بتحديث سجلDataAdapter
و كائن االتصال الالزم، الالزمة لعملية التحديثSQL جديد وإعداده بجملة
. ًأيضا
بعد ذلك نحتاج إلى إضافة البارامترات التي تم تعشيشها في جملة-17
وكذلك البارامتر الخاص بتحديد، مع قيمها الخاصة بها، السابقة الذكرSQL
السجل المراد تحديثه والذي قمنا بتخزين قيمته سابقاً في المتغير
. ) 22 إلى17 ( وكل ذلك نجده في السطور رقم، IdValue
* رقمي ( ) 5 ، 4لست على دراية تامة بها ولكني نقلتها بعد أن قمت
بترجمتها من MSDNلعله يوجد من يستفيد منها أو يوضحها لنا ،ونصها
األساسي هو :
[]ltr
If the command is set to FirstReturnedRecord, the first returned -4
.result is placed in the DataRow
.If there are output parameters, they are placed in the DataRow -5
[]ltr/
مالحظة هامة :يمكن التوسع في هذا األمر ،ولكنا سنكتفي بهذا الحد
من المعلومات ،ومن الجدير بالذكر أننا لم نستخدم بعد عناصر التحكم
المترابطة ،وكذلك باني األوامر الكائن CommandBuilderوالكائنات األخرى
،والتي تختصر لنا الكود بنسبة مرضية جداً ،باإلضافة إلى المرونة وقوة
التحكم ،من أجل ذلك نجد هنا أن الكود طويل ( أرجو أن نصبر قليال ً فهو
في حقيقة األمر اقل بكثير مما هو عليه) ،علماً أن الكود المذكور من أجل
الشرح والفهم لما يدور خلف الكواليس فقط ،وسوف نعيد كتابة االكواد
السابقة بشكل مختصر ،وذلك عندما نتقدم في الدرس قليال ً ..
** هنا ينتهي حديثنا اليوم ،ونأخذ قسطاً من الراحة ،لكي نستوعب هذه
الجرعة من المعلومات ونصحح أخطائها إن وجدت ،ونعلق على الغير
مفهوم منها ،و نكمل فيما بعد شرح ما تبقى من الدرس وذلك في
المشاركات القادمة ..
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك
=============
الكائن : 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 أمر
، وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديالت الجديدة
وفي السطر، DataAdapter بالكائنCommandBuilder وهي ربط الكائن
CommandBuilder التي قامSQL نعرض فيها جملةMsgBox األخير نعرض
.. ببنائها وكذلك عدد البارامترات التي استخدمها
كود
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")
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.Update(ds, "Information")
SQL
INSERT INTO Information (Name, Age, Phone, Email) VALUES (?, ?, ?, ?)
لصنع كائنCommandBuilder ويبين الكود التالي كيف يمكن استخدام-
.. لحذف سجلDataAdapter أمر
، وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديالت الجديدة
وفي السطر، DataAdapter بالكائنCommandBuilder وهي ربط الكائن
CommandBuilder التي قامSQL نعرض فيها جملةMsgBox األخير نعرض
.. ببنائها وكذلك عدد البارامترات التي استخدمها
كود
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")
Me.BindingContext(ds, "Information").RemoveAt(MYPosition)
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.Update(ds, "Information")
SQL
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 أمر
، وسوف نستخدم نفس الكود السابق شرحه مع بعض التعديالت الجديدة
وفي السطر، DataAdapter بالكائنCommandBuilder وهي ربط الكائن
CommandBuilder التي قامSQL نعرض فيها جملةMsgBox األخير نعرض
.. ببنائها وكذلك عدد البارامترات التي استخدمها
كود
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")
Me.BindingContext(ds, "Information").EndCurrentEdit()
instance_adapter.Update(ds, "Information")
SQL
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
كود
)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
** هنا ينتهي حديثنا اليوم ،ونأخذ قسطاً من الراحة ،لكي نستوعب هذه
الجرعة من المعلومات ونصحح أخطائها إن وجدت ،ونعلق على الغير
مفهوم منها ،و نكمل فيما بعد شرح ما تبقى من الدرس وذلك في
المشاركات القادمة ..
مالحظة :موضوعنا القادم سوف يكون " ربط عناصر التحكم Binding
، " Controlsوسوف نتعلم كيف يمكننا إنعاش هذه العناصر وجعلها تنبض
بالحياة ..إلى أن نلتقي مرة أخرى أترككم في حفظ هللا ورعايته ..ياسر
الشيخ
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))
ربط عناصر التحكم -: Binding Controls
مقدمة :تقوم فكرة ربط عناصر التحكم على ربط البيانات المتوفرة في
DataTableأو DataSetبأحد عناصر التحكم الموجودة في واجهة
المستخدم الرسومية على سبيل المثال :
CheckBox ، ComboBox ، DateTimePicker ، Label ، LinkLabel ،
، ListBox
ListView ، MonthCalendar ، PictureBox ، ProgressBar ، RadioButton
،
... RichTextBox ، StatusBar ، TextBox ، TreeView ، DataGridView
هذا فقط على سبيل المثال ال الحصر ،وبعد أن يتم ربط عناصر التحكم
بمصدر البيانات ،فإنه يتم إنعاشها فتصبح تنبض بالحياة ،حيث أن أي
تغييرات تتم على مصدر البيانات ستنعكس تلقائياً عليها وكذلك العكس
حيث أن أي تغيير يتم على قيم هذه العناصر فإنه ينعكس على مصدر
البيانات وفي هذه الحالة لو استدعينا الخاصية HasChangesالتابعة للكائن
DataSetفإنها سوف تعيد القيمة . Trueإضافة إلى أن الربط فيما بين
عناصر التحكم ومصادر البيانات يسهل علينا عملية البحث و اإلبحار والتنقل
بين البيانات الن عناصر التحكم في هذا الحالة سوف تعرض القيم الحالية
للبيانات المتوفرة في مصادر البيانات .
وهو يختص بعناصر التحكم التي تستقبل ( ) single valueأي قيمة حقل
واحد من مصدر البيانات على سبيل المثال TextBox ، Lable ،
DateTimePicker ، PictureBox ، MonthCalendar
وللقيام بعملية الربط سوف نستخدم الكائن ، Bindingونقوم بتجهيزه
للعمل وذلك عن طريق تزويده ببعض المتغيرات ( البارامترات ) وهي
كالتالي :
كود
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
-1بفرض أننا نريد أن نربط أداة تحكم من نوع ListBoxبقيم العمود الذي
يحمل اسم " " Nameوهو أسماء الطالب ،علما أن هذا العمود أحد
أعمدة الجدول Studentsوهذا الجدول مخزن في الكائن ، DataSetوللقيام
بعملية الربط فلنتفحص الكود التالي ..
كود
ListBox1.DataSource = MyDataSet
"ListBox1.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
كود
)"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
كود
DataGridView1.DataSource = MyDataSet
"DataGridView1.DataMember = "CustomerAddresses
كود
)"DataGridView1.DataSource = MyDataSet.Tables("CustomerAddresses
** هنا ينتهي حديثنا اليوم ،ونأخذ قسطاً من الراحة ،لكي نستوعب هذه
الجرعة من المعلومات ونصحح أخطائها إن وجدت ،ونعلق على الغير
مفهوم منها ،و نكمل فيما بعد شرح ما تبقى من الدرس وذلك في
المشاركات القادمة ..
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))
-----------------------------------------------
نصادف أحيانا أثنا قيامنا بعملية التحديث برسائل مزعجة تسمى بإنتهاك التزامن
( ، ) Concurrency violationويكون نص الرسالة كما يلي :
كود
Dim WithEvents MyDataAdapter As New OleDb.OleDbDataAdapter
كود
' Event Handler for RowUpdated Event
Private Sub MyDataAdapter_RowUpdated(ByVal sender As Object, ByVal e As
OleDb.OleDbRowUpdatedEventArgs) Handles MyDataAdapter.RowUpdated
If e.Status = UpdateStatus.Continue AndAlso e.StatementType =
StatementType.Insert Then
'Get NewID
Dim cmdGetIdentity As New OleDb.OleDbCommand("SELECT
@@IDENTITY", cn)
cmdGetIdentity.CommandType = CommandType.Text
' Get the Identity column value
e.Row("ID") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString())
e.Row.AcceptChanges()
End If
End Sub
وبذلك نكون قد تخلصنا من مشكلة انتهاك التزامن حيث لن تظهر عند عملية
التحديث ،وهللا الموفق ،فإن أصبت فبتوفيق هللا وحده ،وإن أخطأت فمن
نفسي والشيطان .أخوكم الفقير إلى هللا ياسر الشيخ ..
مالحظة :عند التطبيق يجب استبدال بعض العبارات بما يتناب مع برامجكم من
االسم الذي اخترتموه لكائن االتصال واسم العمود المخصص للـ Primary Key
وغيره .وللمزيد من المعلومات أحيلكم على الرابطين التاليين :
http://www.msdner.com/dev-archive/150/2-7-1501099.shtm
http://support.microsoft.com/default.aspx?...kb;en-us;815629
((سبحانك اللهم وبحمدك ،أشهد أن ال إله إال أنت ،أستغفرك وأتوب إليك ))