• السابق التالي







  • ابريل
    21
    التعامل مع قواعد البيانات بتقنية Ado.Net عن طريق C#.Net بالوضع المتصل
    2010
    كتـب بـواسطة : مهند بندق , التصنيف : دروس في البرمجة , عدد المشاهدات (5338)

    بسم الله الرحمن الرحيم

    و الصلاة و السلام على سيدنا محمد خاتم الأنبياء و المرسلين ..

    بناء على طلب أحد الزوار لهذه المدونة مستفسرا عن طريقة ربط قواعد البيانات مع الفيجوال أستوديو دوت نت, في هذه التدوينة سأستعمل لغة C#.Net كونها هي الأكثر شيوعا وسلاسة واحترافية من Vb.Net لتلبية هذا الطلب ..

    أولا Ado.Net هي اختصار لـ ActiveX Data Objects أي كائنات التعامل مع قواعد البيانات .. و هي مجموعة من الكائنات تتعامل مع بعضها البعض للوصول إلى مصادر تخزين البيانات واستخدامها أي (إضافة , تعديل ,حذف, قراءة) ... والمقطع .Net أضيف حديثا بعد أن تم تطوير هذه الكائنات لتعمل تحت Dot Net Framework .. وصارت جزءا لا يتجزأ من هذه التقنية ..

    تختلف الكائنات المستعملة حسب نوع قاعدة البيانات وحسب المزود , بشكل عام وعملي نستعمل الكائنات التي من سلالة System.Data.OleDb في التعامل مع قواعد بيانات MS Access عندما نصل إليها عن طريق Path أي المسار على القرص الصلب ونستعمل سلالة System.Data.Odbc عند الوصول إلى قاعدة بيانات معرفة ODBC الموجود في الجهاز , سلالة System.Data.SqlClient للتعامل مع قواعد بيانات SQL Server  ...

    أما الاختلاف بين هذه السلالات أو بأسلوب برمجي ((الكائنات التي تندرج تحت مجالات الأسماء هذه)) فأغلبها موروث من الواجهة نفسها ولكن الاختلاف في طريقة التنفيذ الداخلية لكل سلالة ..أما أنت كمبرمج أو مستخدم لهذه الكائنات لن تلحظ فرقا يذكر في طريقة الاستخدام .. بالتالي هنا سأشرح طريقة التعامل مع مجال أسماء واحد وهو System.Data.OleDb لأني سأستعمل قاعدة بيانات Access لسهولة نشرها وتبادلها عبر شبكة الانترنيت .. وأغلب الأوامر وطرق الاستعمال متناظرة مع السلالات الأخرى , الاختلاف الملحوظ فقط هو نوع البيانات أي نوعية الحقول التي سيتم التعامل معها ..

    كما ان هذه التقنية تتعامل بطريقتين مع قواعد البيانات وهما ((الوضع المتصل , الوضع المنفصل))

    المقصود بالمتصل ستبقى قاعدة البيانات التي تم الاتصال بها مفتوحة إلى حين إغلاقها بعد إتمام القراءة و أو إجراء آخر ,, أما الوضع المنفصل فهو يقرأ البيانات ويخزنها في كائن DataTable والذي يعتبر كجدول وهمي و DataSet والذي يستطيع حضن أكثر من DataTable .. سأتطرق هنا لشرح الوضع المتصل فقط

    التعريف بالكائنات الأساسية في استخدام الوضع المتصل:-

    OleDbConnection : كائن الاتصال و المسئول عن فتح وقفل الاتصال .

    OleDbCommand وهو الذي يستعمل في تنفيذ العمليات و الاستعلامات بعد أن يرتبط بكائن الاتصال ..

    وكائن OleDbDataReader وهذا الذي نستعمله لقراءة أي بيانات من نتائج الاستعلام.

    سأقوم بوضع الصورة العامة لاستعمال هذه الكائنات لأي غرض من الإغراض (الإدخال, و الإضافة, والحذف ثم القراءة))

    في عمليات الإضافة و التعديل و الحذف سنعتمد على جمل SQL ترسل عن طريق كائن الأوامر –إن صح التعريب – OleDbCommand ,وذلك بعد إسناد كائن الاتصال للخاصية Connection وإعطاء جملة الاستعلام التي نريد تنفيذها سواء كانت "Insert Or Update And Delete" وبعدها نقوم بفتح الاتصال لكائن OleDbConnection بالطريقة Open وتنفيذ الاستعلام الموجود في كائن الأوامر وهو بالطريقة ExecuteNonQuery ..

    أما في عملية القراءة فهي تختلف في طريقة تنفيذ الاستعلام عن العمليات السابقة بغض النظر عن الاختلاف في الاستعلام نفسه وهو عن طريق Select لأننا نريد الحصول على نتائج لهذا الاستعلام!, هنا يأتي دور كائن OleDbDataReader الذي سنقوم بحفظ نتائج الاستعلام به ثم نتطرق إلى قراءة النتائج لو وجدت !

    إن لم تفهم ما سبق لا تقلق فسنقوم بتطبيق ذلك عمليا ولكن قبل ذلك أريد أن أشير إلى نقطة أخيرة تهمنا وهي أن في عملية الإدخال و التعديل نستقبل بيانات من المستخدم هذه البيانات قد لا تنطبق مع أنواع الحقول الموجهة إليها , للتحقق من هذه البيانات والتحقق من أمانها يجب تعريف Parameter محددة النوع و الكمية و القيمة ثم إرسالها في جملة استعلامنا.. الآن جاء الجزء العملي :-

    لقد قمت بتصميم جدول بسيط جدا عن طريق MS Access لبيانات الطلبة كما يلي:-

     

    فلدينا جدول باسم StudentsTable وبه الحقول ((StID , St_Name , St_Age)) أي ((حقل الرقم المسلسل – رقمي + مفتاح أساسي, حقل الاسم –نصي , وحقل العمر –رقمي)) على التوالي ..

    الآن سنتولى عملية الإدخال عن طريق Ado.Net  بالوضع المتصل :-

    استدعاء مجال الأسماء في أعلى الصفحة

    using System.Data.OleDb;

    تعريف كائن الاتصال ونسند إليه نص الاتصال في جملة التصريح..

    OleDbConnection MyCon = new

    OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DBNameAndPath.mdb");

    حيث DBNameAndPath.mdb هو مسار واسم قاعدة البيانات ولتعلم المزيد عن نصوص الاتصال باختلاف أنواع قواعد البيانات و المزودات سيفيدك هذا الموقع www.connectionstrings.com

    وسنقوم بتعريف كائن الأوامر نستطيع أن نرسل له جملة الاستعلام وكائن الاتصال أثناء التصريح كما يلي

    OleDbCommand MyCmd =

    new OleDbCommand

    ("INSERT INTO [StudentsTable]([St_Name],[St_Age]) VALUES ('Mohammed',26)"

    ,MyCon);

    حيث Mohammed هو اسم الطالب الجديد و 26 هو عمره .. أو إسناد الاستعلام إلى الخاصية CommandText وكائن الاتصال للخاصية Connection هكذا :

    MyCmd.Connection = MyCon;

    MyCmd.CommandText =

    "INSERT INTO [StudentsTable]([St_Name],[St_Age]) VALUES ('Mohammed',26)";

    كما تلاحظ أني لم استعمل باراميترز لتحديد حجم ونوع ومحتوى القيمتين Mohammed و 26 .. وذلك يتم هكذا ..

    OleDbParameter P_StName =

    new OleDbParameter("@St_Name", OleDbType.VarWChar);

    OleDbParameter P_StAge =

    new OleDbParameter("@St_Age", OleDbType.Integer);

    حيث حددت نوع  P_StName انه نصي VarWChar و نوع P_StAge أنه رقمي Integer .. ولعلك تتساءل عن @St_Name  و @St_Age ماهو إلا تعريف الباراميترز بلهجة SQL لكي تعوض بقيمها في جملة الادخال أو التعديل .. بالتالي سنعيد صياغة جملة الاستعلام الخاصة بنا لتكون هكذا :

    MyCmd.CommandText =

    "INSERT INTO [StudentsTable]([St_Name],[St_Age]) VALUES (@St_Name, @St_Age)";

    في حالة الإدخال , وفي حالة التعديل سنقوم بكتابتها على هذا النحو

    MyCmd.CommandText =

    "UPDATE [StudentsTable] SET [St_Name]=@St_Name ,[St_Age]=@St_Age WHERE [StID]= " + StID;

     

    حيث StID هو قيمة الرقم المسلسل للسجل أو الطالب الذي نود تعديل بياناته ..

    ولا ننسى إسناد القيم الخاصة بنا

    P_StName.Value = "Mohammed";

    P_StAge.Value = 26;

    وسنقوم بإضافة الباراميترز الخاصة بنا إلى كائن الأوامر حتى يقوم بدوره باالتعويض بقيمها في الجمل السابقة كما يلي

    MyCmd.Parameters.Add(P_StName);

    MyCmd.Parameters.Add(P_StAge);

    بعد تجهيز العتاد اللازم للإدخال أو التعديل سنقوم بالتنفيذ كما يلي

    1)      فتح الاتصال.

    2)      تنفيذ الاستعلام.

    3)      قفل الاتصال.

    بالكود التالي :

    MyCon.Open();

    MyCmd.ExecuteNonQuery();

    MyCon.Close();

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

    MyCmd.CommandText =

    "DELETE FROM [StudentsTable] where [StID]=" + St_ID;

    حيث St_ID هو الرقم المسلسل للطالب أو السجل , كما نستطيع تعريفه هو الآخر كباراميتر بتحديد نوعه وحجمه و قيمته ليتم التعويض عنه هكذا

    OleDbParameter P_St_ID =

    new OleDbParameter("@St_ID", OleDbType.Integer);

    P_St_ID.Value = 1;

    MyCmd.Parameters.Add(P_St_ID);

    MyCmd.CommandText =

    "DELETE FROM [StudentsTable] where [StID]=@St_ID";

    ولكن غير مجدية مع قاعدة بيانات Access حسب علمي ولكن هذا ما استعمله في قواعد البيانات الكبيرة مثل SQL Server  .. المهم لنواصل الدرس ..

    تبقت لدينا طريقة قراءة السجلات وهي كما يلي :

    تعريف كائن الأوامر

    OleDbCommand MyCmd = new OleDbCommand();

    إسناد جملة البحث للخاصية CommandText بدون تعريف باراميتر

    MyCmd.CommandText =

    "SELECT * FROM [StudentsTable] where [StID] =1";

    أو

    int St_No = 1;

    MyCmd.CommandText =

    "SELECT * FROM [StudentsTable] where [StID] ="+St_No;

    أو بتعريف باراميتر :

    OleDbParameter P_St_No = new OleDbParameter("@St_No", OleDbType.Integer);

    P_St_No.Value = 1;

    MyCmd.Parameters.Add(P_St_No);

    MyCmd.CommandText =

    "SELECT * FROM [StudentsTable] where [StID] =@St_No";

    ثم استعمال كائن OleDbDataReader هكذا

    OleDbDataReader MyDr = MyCmd.ExecuteReader();

    ليتم تنفيذ الاستعلام وتخزين النتائج في OleDbDataReader ..ولمعرفة هل تتوفر نتائج أم لا نستدعي الخاصية HasRows التي تعود بـ True في حالة توفر سجلات وتعود بـ False في حالة عدم توفرها ثم نقوم قراءة السجلات المتوفرة , قبلها سنقوم بتعريف كائنات لحضن القيم فلتكن من نوع List الموروثة التي تسمح لنا بتعريف قائمة من أي نوع للمتغيرات أو الكائنات حسب اختيارنا الأمر أشبه بمصفوفة غير محددة الطول !

    و الصيغة العامة لتعريف هذا النوع من الكائنات هو

    List<T> MyList = new List<T>();

    حيث T هو نوع الكائن الذي نود تكون قائمة له .. والقوائم التي نحن بحاجتها هي

    List<int> St_ID = new List<int>();

    List<string> St_Name = new List<string>();

    List<int> St_Age = new List<int>();

    وعملية القراءة تكون كالتالي

    while (MyDr.Read())

    {

    St_ID.Add(int.Parse(MyDr["StID"].ToString()));

    St_Name.Add( MyDr["St_Name"].ToString());

    St_Age.Add(int.Parse(MyDr["St_Age"].ToString()));

    }

    علما بأن الاتصال سيبقى مفتوح طالما عملية القراءة مستمرة وان قمنا بإغلاقه ستتوقف عملية القراءة وفي حالة لو أننا نعرف أن النتيجة فقط سجل واحد وهذا المعتاد نحور ما سبق كما يلي

    int St_ID;

    string St_Name;

    int St_Age;

    while (MyDr.Read())

    {

    St_ID = int.Parse(MyDr["StID"].ToString());

    St_Name = MyDr["St_Name"].ToString();

    St_Age = int.Parse(MyDr["St_Age"].ToString());

    }

    استعملت كائنات القوائم في المرة الأولى فقد للاحتفاظ بجميع القيم , كما هي حال المتغيرات في الحالة الثانية , يمكنك التعويض عنها بـأدوات كـ TextBox أو ListBox أو حتى ListView لرؤية النتائج السابقة للاستعلام.

    في النهاية لا ننسى إغلاق الاتصال بـ MyCon.Close() حتى نضمن إغلاق قاعدة بياناتنا وكمعلومة أخيرة يمكنك الاستعلام عن حالة الاتصال لقاعدة البيانات لو كانت مفتوحة أو مغلقة عن طريق الخاصية State التي تعود بـ enum تحدد حالة الاتصال التي منها Open و Closed و Connecting وغيرها التي قد تساعدك لجس نبض قاعدة البيانات..

    في الخاتمة كما ذكرت في البداية تستطيع استعمال نفس الطريقة باختلاف الكائنات التي تعتمد على نوع مزود قاعدة البيانات الخاصة بك.

    إن لم تفهم شيء أو بعض مما سبق – ستفهم يعني ستفهم J - قمت بإنشاء مثال مفتوح المصدر .. موضح داخله كل ما يحتويه هذا الدرس..

    صورة الواجهة

     

    رابط التحميل من هنا

    في النهاية لا تنسونا من صالح دعائكم..

    وإلى اللقاء في درس آخر ,إلى ذلك الحين تقبلوا مني أطيب التحيات ..

    مهند بندق..

    و السلام عليكم ورحمة الله وبركاته

     
    التعليقات (0)




           
    الإسم
    الدولة
    البريد الإلكتروني
    المحتوى  
    أكتب النص الظاهر في الصورة
     


    ابريل
    2
    التعامل مع الرجستري عن طريق C#.Net
    2010
    كتـب بـواسطة : مهند بندق , التصنيف : دروس في البرمجة , عدد المشاهدات (2388)
    لا شك في أنك كمبرمج ستحتاج عاجلا أم آجلا التعامل مع ملفات الرجستي وتخزين قيم فيها وقراءتها عند الحاجة لذلك والتي في العادة ستحتاجها لحفظ خصائص البرنامج التي تقوم بتصميمه أو لاغراض أخرى ..

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


    يناير
    20
    التعامل مع الملفات و المجلدات عن طريق C#.Net -الجزء الثالث- الملفات الثنائية
    2010
    كتـب بـواسطة : مهند بندق , التصنيف : دروس في البرمجة , عدد المشاهدات (3490)
    لقد تناولنا في الأجزاء السابقة من هذا الدرس:

    - التعامل مع الملفات والمجلدات عن طريق C#.Net -الجزء الأول- Your File Explorer.

    - التعامل مع الملفات و المجلدات عن طريق C#.Net -الجزء الثاني- الملفات النصية.

    طرق مختلفة للتعامل مع المجلدات و الملفات بشكل عام و الملفات النصية من حيث فتحها و الكتابة داخلها.

    في هذا الجزء سنتعامل مع جميع أنواع الملفات , مهلا !! ألم تقل الملفات الثنائية ؟!

    نعم فجميع الملفات نصية كانت أو صور أو فيديو , ما هي إلا معلومات ثنائية مخزنة على الهارد ديسك أو موجودة في الرام .. هنا سنقوم بقراءتها وتخزينها في الذاكرة بشكل مؤقت ثم نسخها إلى مكان آخر مثلا .. الخلاصة ما سنتعرف عليه هنا كيفية قراءة الملفات بالبايت والاحتفاظ بها على شكل مصفوفة من البايتات.. وكتابة هذه المصفوفة في ملف آخر .. أو حتى تخزينها في قاعدة البيانات !! ..

     


     
    الصفحات : [1] [2] [3] [4] [5]



    حقوق النشر محفوظة لـ مهند بندق © 2009 - 2019
    Programmed And Designed By : Mohaned Bondoq
    Copyright © 2009 - 2019