تقييم الموضوع :
  • 1 أصوات - بمعدل 1
  • 1
  • 2
  • 3
  • 4
  • 5
[VB.NET] الـDataTable تحت المجهر
#1
Heart 
السلام عليكم ورحمة الله

اليوم، سأكتب عن الـDataTable، وأتمنى لكم الفائدة..

الكلاس DataTable
ويمثل جدولاً واحداً ضمن الـDataSet. وكل جدول لا بد أن تتوفر فيه الكلاسات: DataColumn وDataRow، فللجدول حقول (أعمدة Columns) وسجلات (صفوف Rows). وهذا الكلاس يتبع مباشرة لفضاء الأسماء System.Data.

إنشاء جدول Creating a DataTable
هذا الكلاس يتبع مباشرة لفضاء الأسماء System.Data، ولإنشاء جدول نقوم بتعريف كائن DataTable، وبشكل اختياري يمكننا منحه اسماً:
كود :
Dim UnNamedTable As New DataTable

في السطر السابق تم تعريف كائن يمثل جدولاً دون أن نسميه، وفي السطر التالي، نقوم بتعريف كائن يمثل جدولاً باسم Customers:
PHP كود :
Dim Customers As New DataTable("Customers"

• إذا لم نحدد اسماً للجدول، يقوم ADO.NET بتسميته Table1، والجدول الذي يليه Table2 وهكذا.
• بعد إنشاء كائن الجدول، يمكننا تعديل قيمة الخاصية TableName لإعطائه اسماً أو تعديله، كما يمكننا التعامل مع بقية الخصائص والوظائف والأحداث.

إضافة DataTable إلى DatatSet
يضاف الجدول DataTable المنشأ حديثاً إلى الـDataSet بالصورة التالية:
PHP كود :
Dim EmployeesDataSet As New DataSet("Employees DataSet")
Dim PersonalInfoTable As New DataTable

EmployeesDataSet
.Tables.Add(PersonalInfoTable

وذلك من خلال الوظيفة Add التابعة للخاصية Tables التابعة للـDataSet.

أهم خصائص DataTable:
الخاصية TableName: ومن خلالها يمكن ضبط / استرجاع اسم الـDataTable.
PHP كود :
Dim FirstTable As New DataTable
MsgBox
(FirstTable.TableName)
FirstTable.TableName "Nationalities"
MsgBox(FirstTable.TableName

الخاصية Columns: ومن خلالها يمكن استرجاع تجمع الأعمدة أو الحقول التابعة للـDataTable.
PHP كود :
Private Sub PrintValues(ByVal table As DataTable)
    
Dim row As DataRow
    Dim column 
As DataColumn
    
For Each row in table.Rows
       
For Each column In table.Columns
          Msgbox
(row(column))
       
Next
    Next
End Sub 
وستتضح الصورة أكثر بعد الحديث عن كل من : DataColumn و DataRow.

الخاصية DataSet: ومن خلالها يمكن استرجاع الـDataSet التي يتبعها هذا الـDataTable.
PHP كود :
Dim EmployeesDataSet As New DataSet("Employees DataSet")
Dim PersonalInfoTable As New DataTable("Personal Info")

EmployeesDataSet.Tables.Add(PersonalInfoTable)
MsgBox(PersonalInfoTable.DataSet.DataSetName

الخاصية PrimaryKey: ومن خلالها يمكن ضبط / استرجاع مصفوفة من الأعمدة أو الحقول التي تعمل كمفاتيح أساسية للـDataTable. وسأشرح عنها عند الحديث عن DataColumn.

الخاصية Rows: ومن خلالها يمكن استرجاع تجمع الصفوف التي تتبع هذا الـDataTable. وسأشرح عنها عند الحديث عن DataRow.

أهم وظائف DataTable:
الوظيفة Clear: وتقوم بمسح محتويات الجدول من البيانات فقط، ولا تحذف تركيبته.

PHP كود :
PersonalInfoTable.Clear() 

الوظيفة Clone: وتقوم بنسخ تركيبة الجدول دون البيانات.

PHP كود :
Dim PersonalInfoTable As New DataTable
PersonalInfoTable
.TableName "Original Table"

Dim ClonedTable As New DataTable
ClonedTable 
PersonalInfoTable.Clone()
MsgBox(ClonedTable.TableName

الوظيفة Copy: وتقوم بنسخ تركيبة ومحتويات الجدول إلى جدول آخر .
PHP كود :
Dim PersonalInfoTable As New DataTable
PersonalInfoTable
.TableName "Original Table"

Dim CopiedTable As New DataTable
CopiedTable 
PersonalInfoTable.Copy()
MsgBox(CopiedTable.TableName

الوظيفة ImportRow: وتقوم بنسخ DataRow إلى جدول DataTable مع الاحتفاظ بإعداداته السابقة والقيم التي يحملها. وسأشرح عنها عند الحديث عن DataRow.
PHP كود :
Dim tblItems As New DataTable("Items")

Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)

column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)

tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}

Dim NewRow As DataRow
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 1
.Item("item") = "Milk"
End With

With tblItems
.Rows.Add(NewRow)
.
AcceptChanges()
.
Rows(tblItems.Rows.Count 1).SetAdded()
End With

Dim Newtable 
As New DataTable
Newtable 
tblItems.Clone
With Newtable
.ImportRow(tblItems.Rows(0))
.
AcceptChanges()
.
Rows(Newtable.Rows.Count 1).SetAdded()
.
AcceptChanges()
End With 

الوظيفة Merge(DataTable): وتقوم بدمج الجدول المعطى مع الجدول الحالي. سأشرحها لاحقاً في استعراض العمليات على الجداول.
PHP كود :
Dim tblItems As New DataTable("Items")

Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)

column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)

tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}

Dim NewRow As DataRow
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 1
.Item("item") = "Milk"
End With
tblItems
.Rows.Add(NewRow)

Dim Newtable As New DataTable
Newtable
.Merge(tblItems)
MsgBox(Newtable.Rows(0).Item("id")) 

الوظيفة Merge(DataTable, Boolean): وتقوم بدمج الجدول المعطى مع الجدول الحالي مع إعطاء الإمكانية لحفظ التغييرات من عدمه.
PHP كود :
' Create a new DataTable.
Dim tblItems As New DataTable("Items")

Add two columns to the table:
Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)

column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)

        
' Set primary key column.
tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}


Dim Newtable As New DataTable("MoreFields")
column = New DataColumn("Quantity", GetType(System.Int32))
Newtable.Columns.Add(column)

column = New DataColumn("Description", GetType(System.String))
Newtable.Columns.Add(column)

tblItems.Merge(Newtable, True)
MsgBox(tblItems.Columns(2).ColumnName) 

الوظيفة NewRow: وتقوم بإنشاء DataRow بنفس تركيبة الجدول. بحيث تراعى أنواع البيانات وأحجامها وإعداداتها لكل عمود.
PHP كود :
Dim TheNewRow As DataRow
TheNewRow 
tblItems.NewRow
With TheNewRow
.Item("id") = 1
.Item("item") = "Milk"
End With 

الوظيفة Reset: وتقوم بإعادة ضبط الجدول إلى حالته القديمة. وحذف كافة البيانات المخزنة فيه، بالإضافة إلى الفهارس والعلاقات والأعمدة.

PHP كود :
tblItems.Reset() 

الوظيفة Select: وتقوم باسترجاع مصفوفة تمثل كافة الـDataRows بالجدول.
PHP كود :
Dim CompanyDataSet As New DataSet("Company")
Dim TheSupplierTable As DataTable CompanyDataSet.Tables("Suppliers")
Dim SelectedRows() As DataRow TheSupplierTable.Select() 

ويمكن الوصول إلى كل صف في هذه المصفوفة من خلال الـIndex:

PHP كود :
MsgBox(SelectedRows(0).Item("SupplierName")) 

الوظيفة Select(String): وتقوم باسترجاع مصفوفة تمثل الـDataRows التي تخضع للمعايير المحددة.
PHP كود :
Dim CompanyDataSet As New DataSet("Company")
Dim TheSupplierTable As DataTable CompanyDataSet.Tables("Suppliers")

Dim expression As String
expression 
"JoinData > #01-01-2013#"

Dim SelectedRows() As DataRow
SelectedRows 
TheSupplierTable.Select(expression)

MsgBox(SelectedRows(0).Item("SupplierName")) 

الوظيفة Select(String, String): وتقوم باسترجاع مصفوفة تمثل الـDataRows التي تخضع للمعايير المحددة بترتيب محدد.
PHP كود :
Dim CompanyDataSet As New DataSet("Company")
Dim TheSupplierTable As DataTable CompanyDataSet.Tables("Suppliers")
Dim expression As String "JoinDate > 01/01/2013"
Dim sortOrder As String "SupplierName DESC"
Dim SelectedRows() As DataRow

SelectedRows 
TheSupplierTable.Select(expressionsortOrder)
MsgBox(SelectedRows(0).Item("SupplierName")) 


إضافة أعمدة (حقول) للجدول Adding Columns to DataTable
الحمد لله، وصلنا إلى الجزء المثير والممتع! إذ أنه بعد تعريف الكائن الذي يمثل DataTable، سيكون ذلك الكائن فارغاً، وبالتالي لا نستفيد منه شيئاً! والخطوة القادمة هي بالتأكيد إنشاء الحقول أو Data Columns.
يحتوي فضاء الأسماء System.Data أيضاً على كلاس يسمى DataColumn والذي يمثل حقلاً واحداً في تركيبة الجدول Table Schema.
ولإضافة حقل إلى الجدول، نقوم بتعريف كائن يمثل الجدول:

PHP كود :
Dim Customers As New DataTable("Customers"

ثم نعرف كائناً آخر يمثل الحقل، وأنبه هنا إلى أن الحد الأدنى لتعريف الحقل هو توفير اسم الحقل ونوع البيانات التي يحملها:

PHP كود :
Dim CustomerID As New DataColumn("ID"GetType(Long)) 

ففي السطر السابق، تم تعريف الكائن CustomerID على أنه كائن يمثل حقلاً اسمه ID ونوع بياناته Long.
بقيت خطوة أخيرة، وهي ضم الكائن الجديد للجدول:

PHP كود :
Customers.Columns.Add(CustomerID

وفي السطر السابق، تم استخدام الوظيفة Add التابعة لتجمع الحقول Columns لإضافة الحقل الجديد إلى الجدول. ونفعل ذلك لكل عمود جديد. أو بطريقة أخرى، وهي باستخدام الوظيفة Add التابعة لتجمع الحقول Columns لإضافة حقول جديدة دون تعريف كائنات تمثل كل الحقول:
PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("BirthDay"GetType(Date)) 


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

الخاصية AllowDBNull: وتحمل قيمة منطقية Boolean، وتحدد ما إذا كان من المسموح أن لا يحمل هذا الحقل أية قيمة، أي قيمته = Null.
PHP كود :
Dim column As DataColumn
column 
= New DataColumn("ID"System.Type.GetType("System.Int32"))
column.AllowDBNull True 

أو
PHP كود :
Dim column As DataColumn
column 
= New DataColumn("ID"System.Type.GetType("System.Int32"))
column.AllowDBNull False 

ويمكن استعمال الكلاس System.DBNull لاختبار القيمة قبل تخزينها لاحقاً في هذا الحقل (تلقائياً: كل الحقول تسمح بالقيمة Null):
PHP كود :
If (DBNull.Value.Equals(FieldValue)) Then
    
Do something
End 
If 

وكذلك توجد دالة في فجول بيسك وظيفتها فحص قيم المتغيرات:
PHP كود :
If (IsDBNull(FieldValue)) Then
    
Do something
End 
If 

الخصائص AutoIncrement، وAutoIncrementSeed وAutoIncrementStep: تدير هذه الخصائص عملية الزيادة التلقائية لقيم الحقول التي تحمل هذه الميزة، فعند تطبيقها، يتم زيادة القيم تلقائياً عند إضافة سجلات جديدة بمقادير تتحدد من خلال الخاصيتين AutoIncrementSeed وAutoIncrementStep. وبشكل تلقائي فإن الخاصية AutoIncrement مضبوطة على الوضع False، وبالتالي فإن هذه الآلية لا تعمل.
PHP كود :
Dim column As DataColumn = New DataColumn
column
.DataType System.Type.GetType("System.Int32")
With column
     
.AutoIncrement True
     
.AutoIncrementSeed 1000
     
.AutoIncrementStep 10
End With 


الخاصية ColumnName: وهي خاصية نصية تمثل اسم الحقل. ويتم تحديدها وضبطها وقت إنشاء الحقل.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "CustomerName"
.AllowDBNull True
End With
MsgBox
(column.ColumnName

الخاصية DataType: وتمثل نوع البيانات التي سيحملها الحقل. ويتم تحديدها وضبطها وقت إنشاء الحقل، وإذا ما تم إضافة البيانات، لا يمكن تعديل نوعها.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "FirstName"
.DataType System.Type.GetType("System.String")
End With
MsgBox
(column.DataType.ToString

الخاصية DefaultValue: وتمثل القيمة الافتراضية للحقل، ويمكن لأي حقل أن يحمل قيمة افتراضية، ويتم تخزين هذه القيمة كلما تم إنشاء سجل جديد، ويمكن تعديلها لاحقاً دون أية مشكلة.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "FirstName"
.DataType System.Type.GetType("System.String")
.
DefaultValue "None"
End With
MsgBox
(column.DefaultValue

الخاصية MaxLength: وهي خاصة بالحقول التي تحمل قيماً نصية، وتحدد طول النص الذي سيحمله هذا الحقل، وتلقائياً: قيمته هي -1، بمعنى أنه لا حد لطول النص.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "FirstName"
.DataType System.Type.GetType("System.String")
.
MaxLength 20
.DefaultValue "None"
End With 

الخاصية ReadOnly: حقول القراءة فقط لا يمكن تعديل قيمها في أي سجل قد تمت إضافته فعلاً للجدول، وتلقائياً: جميع قيم الحقول قابلة للتعديل.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "FirstName"
.DataType System.Type.GetType("System.String")
.
ReadOnly True
.DefaultValue "None"
End With 

الخاصية Unique: وهي خاصية منطقية، إذا ضبطت بالقيمة True، فإن الحقل لا يسمح بحمل قيمتين متساويتين، وكذلك في هذا النوع من الحقول لا يمكن تخزين قيمة Null.

PHP كود :
Dim column As New DataColumn
With column
.ColumnName "ID"
.DataType System.Type.GetType("System.Int32")
.
Unique True
End With 
وهناك خاصية تتبع الكلاس DataTable وهي PrimaryKey، ومن خلالها – كما أسلفت - يمكن ضبط / استرجاع مصفوفة من الأعمدة أو الحقول والتي تعمل كمفاتيح أساسية للـDataTable:

PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("BirthDay"GetType(Date))

Customers.PrimaryKey = {Customer.Columns("ID")} 

عند إضافة DataColumn للجدول DataTable، يتم إضافته إلى ما يعرف بـColumns Collection أو تجمع الأعمدة (الحقول). هذه الحقول لا تحمل أية قيم إلى حد الآن، وإنما يتم إضافة البيانات عن طريق ما يعرف بـRows Collection أو تجمع الصفوف والذي يتبع الكائن DataTable كما سنرى لاحقاً إن شاء الله.

إنشاء صفوف جديدة Creating New Rows
إن عملية إنشاء الجداول Creating DataTables وأعمدتها DataColumns هي عملية أساسية قبل المضي قدماً للخطوة اللاحقة وهي: عملية إضافة البيانات للجدول أو "إنشاء سجلات (صفوف Rows) جديدة".
وكما تعلمنا سابقاً، فإننا إذ ننشئ الأعمدة (الحقول DataColumns) إنما ننشئ قوالب لا نهائية من حيث العدد، يمكننا حفظ البيانات فيها بالصورة التي نريد. والآن، أود أن أحدثكم عن الكلاس DataRow..

الكلاس DataRow
ويمثل صفاً كاملاً من الـDataColumns التي يتكون منها الـDataTables. آخذاً في الاعتبار نوع وحجم كل عمود DataColumn في الجدول.

أهم خصائص الكلاس DataRow
الخاصية Item(DataColumn): ومن خلالها يتم ضبط / استرجاع القيمة المخزنة بحقل محدد.

PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("RegistrationDate"GetType(Date))
Customers.PrimaryKey = {Customers.Columns("ID")}

Dim NewRow As DataRow
NewRow 
Customers.NewRow
With NewRow
.Item("ID") = 1
.Item("CustomerName") = "Abubaker Swedan"
.Item("RegistrationDate") = Now.Date
End With

Customers
.Rows.Add(NewRow)
MsgBox(Customers.Rows(0).Item("CustomerName"))
MsgBox(Customers.Rows(0).Item("RegistrationDate")) 
الخاصية Item(Int32): ومن خلالها يتم ضبط / استرجاع القيمة المخزنة بحقل محدد بدلالة رقم فهرسه.
PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("RegistrationDate"GetType(Date))
Customers.PrimaryKey = {Customers.Columns("ID")}

Dim NewRow As DataRow
NewRow 
Customers.NewRow
With NewRow
.Item(0) = 1
.Item(1) = "Abubaker Swedan"
.Item(2) = Now.Date
End With

Customers
.Rows.Add(NewRow)
MsgBox(Customers.Rows(0).Item(1))
MsgBox(Customers.Rows(0).Item(2)) 

الخاصية Item(String): ومن خلالها يتم ضبط / استرجاع القيمة المخزنة بحقل محدد بدلالة اسمه.
PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("RegistrationDate"GetType(Date))
Customers.PrimaryKey = {Customers.Columns("ID")}

Dim NewRow As DataRow
NewRow 
Customers.NewRow
With NewRow
.Item("ID") = 1
.Item("CustomerName") = "Abubaker Swedan"
.Item("RegistrationDate") = Now.Date
End With

Customers
.Rows.Add(NewRow)
MsgBox(Customers.Rows(0).Item("CustomerName"))
MsgBox(Customers.Rows(0).Item("RegistrationDate")) 

الخاصية Table: ومن خلالها يتم استرجاع اسم الجدول DataTable الذي ينتمي إليه الصف.
PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("RegistrationDate"GetType(Date))
Customers.PrimaryKey = {Customers.Columns("ID")}

Dim NewRow As DataRow
NewRow 
Customers.NewRow
With NewRow
.Item("ID") = 1
.Item("CustomerName") = "Abubaker Swedan"
.Item("RegistrationDate") = Now.Date
End With

Customers
.Rows.Add(NewRow)
MsgBox(NewRow.Table.TableName
أهم وأشهر وظائف DataRow:
الوظيفة Delete: وتقوم بحذف الـDataRow.

PHP كود :
Dim tblItems As New DataTable("Items")

Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)
column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)

tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}

Dim NewRow As DataRow
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 1
.Item("item") = "Milk"
End With

With tblItems
.Rows.Add(NewRow)
.
AcceptChanges()
.
Rows(tblItems.Rows.Count 1).SetAdded()
End With
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 2
.Item("item") = "Cheese"
End With

With tblItems
.Rows.Add(NewRow)
.
AcceptChanges()
.
Rows(tblItems.Rows.Count 1).SetAdded()
End With

MsgBox
(tblItems.Rows.Count)

tblItems.Rows(0).Delete()
tblItems.AcceptChanges()
MsgBox(tblItems.Rows.Count

وكما تلاحظون في الكود، فإنني استعملت الوظيفة AcceptChanges لتأكيد الحذف. وسنتطرق لها في معالجة الحزم لاحقاً إن شاء الله.

الوظيفة IsNull(DataColumn): وتحدد ما إذا كانت القيمة التي يحملها الـDataColumn هي Null.

PHP كود :
If NewRow.IsNull(ColumnObjectThen
MsgBox
("Empty Column")
Else
MsgBox("it is not null value")
End If 


الوظيفة IsNull(Int32): وتحدد ما إذا كانت القيمة التي يحملها الـDataColumn (بدلالة فهرسه) هي Null.

PHP كود :
If NewRow.IsNull(1Then
MsgBox
("Empty Column")
Else
MsgBox("it is not null value")
End If
الوظيفة IsNull(String): وتحدد ما إذا كانت القيمة التي يحملها الـDataColumn (بدلالة اسمههي Null.
If 
NewRow.IsNull("CustomerName"Then
MsgBox
("Empty Column")
Else
MsgBox("it is not null value")
End If 

يدعم الكلاس DataTable الطريقة NewRow لتوليد صف جديد يخضع لإعدادات الـDataColumns، من حيث نوع الحقل وطوله وخصائصه الأخرى وذلك لكل حقل من الحقول التي يحتوي عليها DataTable.
ولفتح صف (سجل DataRow) جديد في الجدول:
PHP كود :
Dim TheNewRow As DataRow TableName.NewRow() 

بعد تنفيذ السطر البرمجي السابق، يتم وبشكل تلقائي إنشاء صف بيانات جديد بحيث يراعى فيه خصائص كل حقل، ويتم وضع القيمة Null في كافة الحقول، عدا تلك التي لها قيم افتراضية Default Values، أو التي خاصية AutoIncrement لها = True.
هناك المزيد من هذه الوظائف، سأتطرق لها لاحقاً مثل الوظيفة SetAdded وSetModified.


ضبط قيم الحقول في الـDataRow الجديد
يتضمن الكلاس DataRow خاصية مهمة وهي Item، والتي تعطي إمكانية الوصول إلى كل DataColumn معرّف في الـDataTable اعتماداً على اسم الحقل أو رقم ترتيبه (ابتداء من الصفر) أو متغير يمثل الـDataColumn، و السنّة المتبعة هي الاعتماد على اسم الحقل تجنباً لأخطاء غير مقصودة، وتوضيحاً للكود، مع الأخذ في الاعتبار خصائص كل حقل على حدة.

PHP كود :
Dim TheNewRow As DataRow TableName.NewRow()
TheNewRow.Item("ID")= 100
TheNewRow
.Item(0)= 100
Dim SpecificRow 
As DataColumn TableName.Columns(0)
TheNewRow.Item(SpecificRow)= 100 

في الكود السابق تم ضبط قيمة أول حقل في الجدول (ID) من خلال اسم الحقل مرة، ورقم ترتيبه مرة ، ومن خلال مرجع يمثل الحقل المطلوب مرة ثالثة.
الخاصية Item هي الخاصية التلقائية للكلاس DataRow، ولذلك يمكن الاستغناء عن ذكرها وكتابة:

PHP كود :
Dim TheNewRow As DataRow TableName.NewRow()
TheNewRow("ID")= 100 

كما يمكن استعمال علامة التعجب (!) لتشير إلى اسم الحقل (لا تدعم رقم فهرس الحقل) في الجدول:

PHP كود :
Dim Customers As New DataTable("Customers")
Customers.Columns.Add("ID"GetType(Long))
Customers.Columns.Add("CustomerName"GetType(String))
Customers.Columns.Add("RegistrationDate"GetType(Date))
Customers.PrimaryKey = {Customers.Columns("ID")}
Dim NewRow As DataRow
NewRow 
Customers.NewRow
NewRow
!ID 1
NewRow
!CustomerName "Abubaker Swedan"
NewRow!RegistrationDate Now.Date
Customers
.Rows.Add(NewRow


حفظ البيانات في الجدول DataTable
بعد ضبط وتعيين القيم في السجل الجديد، تكون الخطوة اللاحقة هي ضم هذا السجل إلى الجدول DataTable، مستعملين الطريقة .Rows.Add التابعة للـDataTable:
PHP كود :
Dim TheNewRow As DataRow TableName.NewRow()

TheNewRow.Item("ID")= 100
TableName
.Rows.Add(TheNewRow

كما يمكن استعمال طريقة أخرى، وهي بتنفيذ الطريقة Rows.Add وإرسال قيم الحقول كبارامترات:
PHP كود :
Dim TheNewRow As DataRow TableName.NewRow()
TableName.Rows.Add(100“Abubaker”“Tripoli”

وأي طريقة اخترنا، فإن الوظيفة Add تختبر القيم المرسلة من حيث توافقها مع تركيبة الجدول وحقوله، وترفض القيم التي لا تتماشى مع القواعد.

الوصول إلى الصف المطلوب في جدول DataTable
أو بصيغة أخرى، طريقة تحديد صف معين أو مجموعة من الصفوف في جدول لإجراء عمليات عليها. وتوجد عدة طرق لاسترجاع الصفوف المطلوبة منها:
أ) استرجاع الصفوف بدلالة قيم الأعمدة
وذلك باستخدام الوظيفة Select Method، التابعة للـDataTable
PHP كود :
Dim foundRows() As Data.DataRow
foundRows 
DataSet1.Tables("Customers").Select("LastName = 'Swedan'"

ففي هذا الكود تم تعريف مصفوفة لتجمع بداخلها الصفوف المسترجعة من عملية البحث باستخدام الطريقة Select، والتي مررنا لها قيمة الحقل LastName. فإن تم العثور على السجلات المطلوبة فإنها تخزن في تلك المصفوفة.

ويمكن معرفة عدد الصفوف المسترجعة من خلال الكود التالي:

PHP كود :
Dim RowsCount As Integer
RowsCount 
foundRows.Count 

ويمكن الوصول إلى حقول كل صف بالكيفية التالية:
PHP كود :
Dim FirstColValue As Integer
FirstColValue 
foundRows(0).Item("OrderID"

ب) استرجاع الصفوف بدلالة قيمة الحقل المفتاحي Primary Key Value
وفي هذه الحالة نستخدم الطريقة Find التابعة للتجمع DataRowCollection ونرسل لها القيمة المفتاحية كبارامتر:
PHP كود :
Dim s As String "primaryKeyValue"
Dim foundRow As DataRow dataset1.Tables("Customers").Rows.Find(s)

If 
foundRow IsNot Nothing Then
    MsgBox
(foundRow(1).ToString())
Else
    
MsgBox("A row with the primary key of " " could not be found")
End If 

تعديل البيانات في الجدول DataTable
لتعديل بيانات أي صف في جدول DataTable، يلزمنا كبداية تحديد الصف المطلوب تعديل بياناته، ومن ثم إسناد القيم المناسبة لكل حقل من حقوله.
ولمعرفة الصف المطلوب تعديله، نستخدم الطريقة Select Method التابعة للـDataTable بالصورة التالية:
PHP كود :
Dim customerRow() As Data.DataRow
customerRow 
DataSet1.Tables("Customers").Select("CustomerID = 107")

customerRow(0)("CompanyName") = "New Company Name"
customerRow(0)("City") = "Tripoli" 

ففي الكود السابق، الحقل CustomerID هو الحقل المفتاحي للجدول Primary Key، وبالتالي عند استخدام الطريقة Select وتمرير رقم الزبون فإن النتيجة هي إرجاع مصفوفة customerRow() تحتوي على صف واحد فقط، إذ أن رقم الزبون لا يتكرر. ثم استعملنا الرقم (0) للتعبير عن أول صف مسترجع في المصفوفة، وعدلنا قيم الحقول المقصودة.
بالإمكان تعديل الكود السابق والخاص بضبط القيم إلى:
PHP كود :
customerRow(0).Item("CompanyName") = "New Company Name"
customerRow(0).Item("City") = "Tripoli" 

ولكن كما قلتُ سابقاً أن الخاصية Item هي الخاصية التلقائية للكلاس DataRow، ولذلك يمكن الاستغناء عن ذكرها.
وفي حالة أننا نعلم رقم ترتيب الصف المطلوب تعديله، بدلالة رقم الجدول في الـDataSet نكتب:
PHP كود :
DataSet1.Tables(0).Rows(4).Item(1) = "New Company Name"
DataSet1.Tables(0).Rows(4).Item(2) = "Tripoli" 

أو بدلالة اسم الجدول:
PHP كود :
DataSet1.Tables("Customers").Rows(4).Item(1) = "New Company Name"
DataSet1.Tables("Customers").Rows(4).Item(2) = "Tripoli" 


عرض بيانات الجدول Viewing Data in a DataTable
يمكننا الوصول لبيانات الجدول من خلال استعمال التجمعات Rows وColumns الخاصة بالـDataTable. وكذلك استعمال الطريقة Select Method لاسترجاع مجموعة من السجلات التي تخضع لشروط معينة وترتيب معين وحالة صف معينة.
بالإضافة إلى استعمال الطريقة Find Method التابعة للتجمع DataRowCollection للبحث عن سجل معين عن طريق مفتاحه الأساسي.
استعمال الطريقة Select Method يرجع مجموعة من كائنات الـDataRow ، تنطبق عليها شروطنا، وتقبل بارامترات تمثل:
• صيغة الفرز (الشروط) Filter expression.
• طريقة الترتيب Sort expression.
• حالة كل صف DataViewRowState.

صيغة الفرز تحدد الصفوف المسترجعة بناء على قيم الحقول DataColumn مثلاً LastName = “Swedan”.
وطريقة الترتيب تحدد من خلال جملة Sql مثلاً ORDER BY LastName DESC.
أما حالة كل صف فسنتعرف عليها لاحقاً إن شاء الله في موضوع: حالة الصف Row State.

حذف البيانات من جدول Removing Data from DataTable
يمكن حذف الصفوف من الجدول DataTable باستخدام:
• الطريقة Remove التابعة للتجمع DataTable.Rows.
• الطريقة RemoveAt التابعة للتجمع DataTable.Rows.
والطريقة Remove Method تأخذ متغيراً يمثل صفاً في الجدول:
PHP كود :
Dim SelectedRow As DataRow SelectedTable.Rows(0)
SelectedTable.Rows.Remove(SelectedRow

أما الطريقة RemoveAt Method فتأخذ رقم فهرس الصف مباشرة:

PHP كود :
SelectedTable.Rows.RemoveAt(0

وكل الطرق تؤدي إلى مكة.
ويمكن حذف جميع الصفوف بأمر واحد، وذلك باستخدام الطريقة Clear Method التابعة للكائن DataTable.Rows:

PHP كود :
SelectedTable.Rows.Clear() 

ويجب ملاحظة أنه عند حذف الصفوف بهذه الطريقة، فإنه لا يمكننا التراجع عن عملية الحذف إطلاقاً، وهذا ما سنفهمه من الموضوع التالي.

معالجة الحزم / الدفعات Batch Processing
جميع العمليات التي قمنا بها سابقاً هي عمليات مباشرة تتم على سجلات الجدول وحقوله، الأمر للوهلة الأولى جيد ورائع، ولكن لهذا النظام عيوب منها عدم القدرة على استرجاع قيم سابقة للحقول، ولا يمكن التراجع عن أي عملية والرجوع إلى الحالة السابقة.
ADO.NET يوفر مزايا جديدة بحيث يمكننا عمل تغييرات على عدة سجلات، وبعدها نقرر هل نطبق هذه التغييرات أم نتجاهلها! وهذه الطريقة تسمى: معالجة الحزم أو الدفعات.
وللاستفادة من هذه الطريقة في المعالجة، ببساطة نقوم بإحداث التغييرات التي نريد، وعندما نكون جاهزين لتطبيق هذه التغيرات:
• نستخدم الطريقة AcceptChanges Method التابعة للـDataTable ليتم تطبيق التغييرات وتحديث بيانات الجدول.
• أو نستخدم الطريقة RejectChanges Method لرفض التغييرات غير المحفوظة والحفاظ على بيانات الجدول كما هي دون تغيير.

يمكن تطبيق هاتين الطريقتين حتى على الـDataRows. فكل DataRow يدعم هاتين الطريقتين، ولكن استخدام AcceptChanges أو RejectChanges على الجدول بأكمله أفضل من استعمالهما مع كل صف على حدة، لأنه سيتم الدوران على كافة الصفوف التي حدث بها التغيير وتطبيقها (في حال استعمال AcceptChanges) أو رفض التغييرات (في حال استعمال RejectChanges).
PHP كود :
SelectedTable.AcceptChanges()
SelectedTable.RejectChanges() 


حالة الصف Row State
في أثناء إجراء التغييرات على الصف، يقوم ADO.NET بحفظ النسخة الأصلية والنسخة المعدلة لكافة الحقول التي يحتويها هذا الصف، وكذلك بمراقبة وتحديد الصفوف المضافة و/أو المحذوفة من الجدول، بحيث يمكن أن نعود للنسخة الأصلية حين الحاجة. يفعل ADO.NET كل ذلك من خلال حفظ حالة كل حقل لكل الصفوف ويتم تحديث قيمة الخاصية DataRow.RowState لكل صف على حدة، والتي تحتمل إحدى القيم التالية:
• DataRowState.Detached: وهي الحالة الافتراضية لأي صف لم يتم إضافته بعد إلى DataTable.
• DataRowState.Added: وهي حالة كل صف تم إضافته إلى DataTable ولكن لم تأكيد الإضافة. بحيث لو استعملنا RejectChanges يتم حذفها فوراً.
• DataRowState.UnChanged: وهي الحالة الافتراضية لأي صف موجود مسبقاً بالجدول ولم تتم عليه أي عملية تعديل منذ آخر مرة تم فيها استدعاء الطريقة AcceptChanges Method. وهي الحالة الافتراضية أيضاً لكافة السجلات التي تم إنشاؤها من خلال الطريقة NewRow.
• DataRowState.Deleted: الصفوف المحذوفة لا يتم إزالتها فعلياً من الجدول إلى أن يتم استدعاء الطريقة AcceptChanges، بل يتم تأشيرها على أنها ستحذف من خلال هذه الخاصية.
• DataRowState.Modified: أي صف تم تعديل حقوله بأي طريقة يؤشر على أنه Modified.

ففي كل مرة نقوم بإضافة أو تعديل صف، يتم تحديث حالته فوراً، على عكس عملية الحذف من خلال Rows.Remove و Rows.RemoveAt، فإنه يحدث التفاف حول نظام تتبع حالات السجلات هذا، ولا يتم تحديث الحالة على نفس المنوال، لأنه يتم حذف الصفوف مباشرة، ولا يجعلها تخضع لنظام معالجة الحزم.
ولحل هذه المشكلة، نستعمل الطريقة Delete Method التابعة للـDataRow عوضاً عن Rows.Remove و/أو Rows.RemoveAt، فهي لا تقوم بحذف الصفوف، بل بتغيير حالتها إلى Deleted، وبالتالي نستطيع تأكيد الحذف من خلال الطريقة AcceptChanges، أو التراجع عن الحذف من خلال RejectChanges.

PHP كود :
TheRow.Delete() 

عند استدعاء الطريقة AcceptChanges سواء من خلال DataSet أو DataTable أو DataRow فإن يتم حذف كافة السجلات التي حالتها = Deleted، وتطبيق التعديلات التي حصلت على السجلات الأخرى بحيث تحل القيم الجديدة Current Values محل القيم الأصلية Original Values.
أما عند استدعاء الطريقة RejectChanges، فإنه يتم حذف كافة السجلات التي حالتها = Added، وتعطى باقي السجلات الحالة Unchanged، وتلغى التعديلات التي حصلت على السجلات الأخرى بحيث تحل القيم الأصلية Original Values محل القيم الجديدة Current Values.


وظائف أخرى للـDataRow
هناك بعض الوظائف الإضافية التي لم أذكرها عند حديثي عن الـDataRow ، مهمة تلك الوظائف هي ضبط حالة الصف مثل:
الوظيفة SetAdded: تقوم بتغيير الـDataState للـDataRow إلى Added.
PHP كود :
Dim tblItems As New DataTable("Items")

Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)
column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)

tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}

Dim NewRow As DataRow
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 1
.Item("item") = "Milk"
End With

With tblItems
.Rows.Add(NewRow)
.
AcceptChanges()
.
Rows(tblItems.Rows.Count 1).SetAdded()
End With 

الوظيفة SetModified: تقوم بتغيير الـDataState للـDataRow إلى Modified.
PHP كود :
Dim tblItems As New DataTable("Items")
Dim column As New DataColumn("id"GetType(System.Int32))
column.AutoIncrement True
tblItems
.Columns.Add(column)
column = New DataColumn("item"GetType(System.String))
tblItems.Columns.Add(column)
tblItems.PrimaryKey = New DataColumn() {tblItems.Columns(0)}

Dim NewRow As DataRow
NewRow 
tblItems.NewRow
With NewRow
.Item("id") = 1
.Item("item") = "Milk"
End With
With tblItems
.Rows.Add(NewRow)
.
AcceptChanges()
.
Rows(tblItems.Rows.Count 1).SetAdded()
End With
With tblItems
.Rows(0).Item("item") = "Cheese"
.AcceptChanges()
.
Rows(0).SetModified()
End With 

نُسخ الصف Row Versions
عند إجراء التعديلات والتغييرات سواء إضافة أو حذف أو تعديل في بيانات الصفوف، فإن ADO.NET يحتفظ بنسخ متعددة لكل صف حتى ولو تم تغيير قيمة حقل واحد فقط.
DataRowVersion
ويحتمل إحدى القيم التالية:
• DataRowVersion.Original: يعني الاحتفاظ بالقيم الأصلية للحقول منذ آخر استدعاء للطريقة AcceptChanges، ولا يشمل الصفوف الجديدة.
• DataRowVersion.Porposed: يعني أن قيمة حقل ما تغيرت، ولكن لم يتم تأكيد التغيير. هذه النسخة لا تتوفر حتى يتم البدء في عملية تعديل قيمة الحقل. بعد تأكيد التغييرات، تتحول القيمة إلى Original.
• DataRowVersion.Current: يعني أن التعديل جارٍ الآن، وعند تأكيده، تتحول القيمة إلى Original.
• DataRowVersion.Default: يعني النسخة التلقائية للصف. فالنسخة التلقائية للـ Added وModified وUnchanged هي Current، والنسخة التلقائية للـDeleted هي Original، والنسخة التلقائية للـDetached هي Proposed.
حيث Added وModified وUnchanged وDeleted و Detached هي حالات الصفوف.


فحص التغييرات الطارئة على محتويات جدول
قلتُ سابقاً أنه عند استعمال نظام معالجة الحزم، وفي حال حدث تغيير في الجدول، لا يتم تطبيق التعديلات إلا عند استدعاء الطريقة AcceptChanges Method. وبالتالي فالتغييرات تبقى معلقة pending حتى تطبيقها أو تجاهلها وإرجاع الجدول إلى سابق عهده (إلى حالته عند استدعاء AcceptChanges آخر مرة). وقلتُ أن عملية تتبع الصفوف تتم عن طريق:
• كل صف يحتوي على "RowState" وهي إحدى الحالات: Detached وAdded وModified وDeleted وUnchanged.
• كل صف تم تغيير محتوياته يتضمن نُسخاً مختلفة للصفوف: Original وProposed وCurrent وDefault.

معرفة ما إذا كان هناك تغيير في الصفوف
هناك طريقة Method تتبع الـDataSet هي: HasChanges، ذات قيمة منطقية، إذا ساوت True فإن هناك تغيير حدث على بعض الصفوف أو كلها. وفي تلك الحالة يمكن استدعاء الطريقة GetChanges التابعة للـDataSet و/أو للـDataTable لاسترجاع مصفوفة تحتوي على الصفوف المتغيرة، وهذه المصفوفة هي بمثابة DataSet أو DataTable مملوء بالصفوف المتغيرة فقط. ومن نافلة القول أنه يجب استدعاء الطريقة GetChanges قبل تطبيق التغييرات باستخدام الطريقة AcceptChanges، وإلا فلن نتحصل على أي صف!.
أ) استرجاع الصفوف المتغيرة من DataSet
وهنا نقوم بإنشاء DataSet وملئها بالصفوف المتغيرة:

PHP كود :
Dim changedRecords As DataSet dataset1.GetChanges() 


ب) استرجاع الصفوف المتغيرة من DataTable
وهنا نقوم بإنشاء DataTable وملئه بالصفوف المتغيرة:

PHP كود :
Dim changedRecordsTable As DataTable Customers.GetChanges() 


ج) استرجاع الصفوف المتغيرة بحسب نوعية التغيير (النسخة)
وهنا نرسل نوع الإصدارة إلى الطريقة GetChanges كبارامتر:

PHP كود :
Dim addedRecords As DataSet dataset1.GetChanges(DataRowState.Added


---------------
الرد }}}
#2
ما شاء الله .. مجهود رائع و بارك الله فيك أخي الكريم ابو بكر ... و لكن ملاحظة من أخوك الصغير Smile

لو كان المقال طويل هكذا فأنصحك بتقسيمه إلى أكثر من جزء ليسهل على القاريء قرائته ...



السلام عليكم
الرد }}}
تم الشكر بواسطة: 30june , asemshahen5
#3
السلام عليكم
كلام جميل

ولكن في النسخة الحالية للمنتدى لم أستطع فعل هذا!
فإن وضعت كل موضوع في رد يظهر في صفحة واحدة.

يمكنك أن تجرب Big Grin
الرد }}}
تم الشكر بواسطة: hoob computer , asemshahen5 , ahmed_king2023 , ahmed_king2023


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  [VB.NET] الـDataSet تحت المجهر أبوبكر سويدان 5 4,895 26-01-14, 03:51 PM
آخر رد: hoob computer

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم