هذا الدرس من أهم الدروس التي سنتعامل معها خلال تعاملنا مع تطبيقات الدوت نت سواء المتعلقة ببناء تطبيقات الويب أو تطبيقات الويندوز لذا أتمنى منك إن لم تستطع فهم نقطة معينة أن تحاول مرة و مرتين إلى أن تستوعب هذه النقطة و أنا سأحاول التشعب في شرح متعلقاتها و التوسع فيها و تبسيط الأمثلة قدر الإمكان و طرح عدة طرق للكتابة حتى لا يحدث لك لبس عند تغيير المراجع حيث أن ال DataSet تكتب بعدة طرق.
ال dataset هي عبارة عن طبقة معرفة من تقنية ال XML يطلق عليها تحديدا ال XSD و هي إختصار لل XML Schema Definition و هي طبقة بيانات تقوم بتخزين وصف دقيق لنوعية البيانات التي تحتويها كما تحدد نوع العلاقات بين البيانات و مفاتيح البيانات Keys و القيود Constrains المنفذة على ال DataSet.
من أجل الوصول لقدر ممتاز من المعلومات و قدرة على التحكم بشكل أكبر عليك الإستزادة في هذه المواضيع التي سأذكرها هنا :
XML
XSD
XPath
XSL
XSLT
هذه كلها متعلقات بال XML و التي أعلنت ميكروسوفت بأنها ستصبح في تطبيقاتها كالملح على الطعام و هذا يجعلنا لا نشك بأهمية تعلم ال XML .
سوف أشرح نبذة بسيطة فقط عن ال XSD التي هي طبقة البيانات المخزنة على شكل ال dataset كي نستوعب الأمور بشكل أكبر . في البداية يتم تعريف العناصر في ال XSD بهذا الشكل :
<xsd : attribute form = "http://domain.com/file.xsd" id = "id number" name = "name of element" ref = "reference name" type = "data type" use = "default or fixed or required" value = "the value" > </xsd : attribute>
كما نرى أننا قمنا بعمل وسم Tag يبدأ ب xsd من أجل تعريف وحدة XSD و التي يطلق عليها إسم Attribute ثم أعطيناها بعض الخصائص مثل form و التي تحدد مكان طبقة XSD تحوي بيانات معينة نحتاجها هنا و هي إختيارية و قد تحوي على إسم صفحة في نفس التطبيق أو على عنوان لصفحة على سيرفر أخر. كما يوجد id و هي خاصية و تحوي على رقم يعبر عن رقم الوحدة و إسم name يحمل إسم العنصر و ref و هي إسم لمرجع معين و type كي يتم تحديد نوعية البيانات و يجب أن تكون هذه النوعية من البيانات معرفة لل XML و ليست ال data type الموجودة في الدوت نت نفسها لتعريف نوعية البيانات و يجب مراجعة مراجع لل XML للوصول لنوعية البيانات المقبولة بها. ثم هناك الخاصية use و هي تحدد نوعية إستخدام البيانات المخزنة إن كانت بالشكل العادي default أو fixed و هي عندما لا تتغير البيانات و تستخدم في العرض فقط و required و هي تجعل البيانات تظهر مرة واحدة فقط عند الحاجة لها.
و لنأخذ مثالا صغيرا من DtaSet تم تعبئتها بالبيانات كي تتضح الصورة أكثر :
<xsd : group name="Users"> <xsd : all> <xsd : element name = "userName" type = "xsd : string"/> <xsd : element name = "userAddress" type = "xsd : string"/> <xsd : element name = "email" type = "xsd : anyUrl"/> </xsd : all> </xsd : group>
رأينا كيف يتم تخزين البيانات في ملفات ال XSD و كان هذا فقط مجرد عرض لك كي تعرف ما يدور من وراء الكواليس أما الان فسنعود لدرسنا و طبعا في البداية لا يطلب منك أن تكون على إلمام بال XML و لكن أنا قلت من أجل زيادة المعرفة و التحكم الأكبر بالتطبيق.
عند العمل مع ال DataSet تحتاج إلى بعض كلاسات ال ADO.NET التالية :
1.DataAdapter
2.DataSet
3.DataTable
4.DataRelation
5.DataView
قلنا في درس سابق و هو ال DataAdapter الموجود في هذا القسم أنه عند كل مرة يتم إستخدام الطريقة Fill سوف يتم إضافة جدول بيانات DataTable إلى ال DataSet و بالتالي ال DataSet قد تحوي على جدول بيانات واحد أو أكثر و قد لا تحتوي أبدا و هي عبارة عن نسخ من جداول موجودة في قواعد البيانات المتصل بها التطبيق عن طريق جمل إستعلام منفذة و قد تكون هذه الجداول منسوخة بشكل متطابق أو جزئي.
ال DataRealation تقوم بتعريف علاقات بين الجداول و ال DataView تقوم بعمليات مثل فلترة البيانات أو ترتيبها كما أن هذين الكلاسين بالإضافة إلى ال dataTable و ال DataSet موجودة ضمن NameSpace و هو System.Data أما ال DataAdapter فله كلاسات منشقة عن ال System.Data و كلنا نعرف أن ال dataAdapter هو وسيط ما بين مصدر البيانات و ال DataSet و قلنا أيضا أن في حالة إستخدام ال dataAdapter فإن البيانات تخزن على جهاز العميل ثم عند إجراء حدث معين مثل التعديل على البيانات سوف يقوم ال DataAdpater بالتأثير على البيانات المخزنة في مصدر البيانات على حسب التغيرات الموجودة في ال DataSet التي تكونت على جهاز العميل نتيجة طلبه لبيانات معينة.
إضافة جدول بيانات DataTable إلى ال DataSet :
من أجل القيام بذلك يلزمنا إتباع عدة خطوات كالتالي :
1.إنشاء ال DataSet .
2.إنشاء الإتصال Connection.
3.إنشاء DataAdapter يمرر له إستعلام SQL و إسم الإتصال.
4.إستدعاء الطريقة Fill الخاصة بال DataAdapter و تمرير إسم ال DataSet لها بالإضافة لل DataTable.
هل يمكن أن أرى مثالا يوضح ذلك؟؟؟
طبعا يمكنك ذلك و دعونا نرى هذا المثال التالي لأنه يشرح الخطوات الأربعة بشكل مبسط جدا و لطيف.
ملاحظة : أنا كتبت الطريقة في درس ال dataAdapter و لكن بلغة ال #C و لكن هنا سأكتبه بلغة ال VB.NET كي لا يغضب علينا أنصار اللغة الأخرى
// VB.NET + SQL Server
Dim ds As DataSet
Dim cn As SqlConnection
Dim da As SqlDataAdapter
ds = new DataSet()
cn = new SqlConnection("Server=localhost; database=db; UID=sa;PWD=123")
da = new SqlDataAdapter("SELECT * From Students",cn)
da.Fill(ds)كما نرى أننا قمنا بالخطوات الأربعة التي ذكرناها و هي إنشاء dataset ثم إنشاء إتصال و من بعدها تعريف dataAdapter مررنا له جملة إستعلام و إسم الاتصال ثم استدعينا الطريقة fill و لكن هناك نقطة مهمة أود أن تنتبهوا لها.
عندما إستدعينا الطريقة Fill تم تخزين جدول في ال dataset و لكن ما هو إسمه و كيف سنتعامل معه ؟؟
الجواب أنه تم تخزين الجدول كما هو موجود في جملة الإستعلام أي Students و لكن يمكننا التخزين بأي إسم اخر و ذلك بإستبدال السطر الأول بالسطر الثاني في هذا المثال :
da.Fill(ds) da.Fill(ds,"NewTableName")
و بالتالي سوف يخزن الجدول بهذا الإسم الجديد و ليس كما هو في جملة الإستعلام و هي الحالة ال default .
و لمستخدمي الأكسيس هذا المثال مرة أخرى لكم :
// VB.NET + MS Access
Dim ds As DataSet
Dim cn As OleDbConnection
Dim da As OleDbDataAdapter
ds = new DataSet()
cn = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;data source=" & Server.MapPath("db.mdb"))
da = new OleDbDataAdapter("SELECT * From Students",cn)
da.Fill(ds)و السؤال الذي قد يأتي في مخيلة أي منا. هل نحتاج لعمل dataset جديدة لكل جدول نحتاجه ؟؟؟
طبعا لا و لم نحن قلنا أن ال dataset تدعم العلاقات بين الجداول و غيرها من الإمتيازات ؟ من المؤكد أن لا حاجة إلا ل DataSet واحدة و نقوم فقط بعمل Fill لل dataAdapter على حسب الإستخدام و كل مرة نقوم بتسمية الجدول بإسم مختلف و بالتالي سنحصل على DataSet على شكل طبقات من الجداول.
سنأخد مثالا توضيحيا :
// VB.NET + SQL Server
Dim ds As DataSet
Dim cn As SqlConnection
Dim da As SqlDataAdapter
ds = new DataSet()
cn = new SqlConnection("Server=localhost; database=db; UID=sa;PWD=123")
cn.Open()
da = new SqlDataAdapter("SELECT * From Students",cn)
da.Fill(ds,"table1")
//الان إضافة جدول ثاني
da.SelectCommand = new SqlCommand("SELECT * From classes",cn)
da.Fill(ds,"table2")
cn.Close()قمنا بتعبئة جدول أول Table1 في ال dataset يحوي بيانات الطلاب ثم قمنا بإضافة جدول أخر Table2 لنفس ال dataset كما رأينا في المثال .
محمد خليل أبو صلاح


