الوصول إلى قواعد بيانات من لغة C# باستخدام ADO

الوصول إلى قواعد بيانات من لغة C# باستخدام ADO

Abo Ahmedمنذ 5 سنوات

مقدمة حول ADO.NET

ADO.NET ممكن تستخدم مع أربعة انظمة ادارة قواعد بيانات (client namespaces) مختلفة: SQL Server ، Oracle، ODBC ، و OLEDB.

Namespaces:

الكلاسات  Classesوالواجهات interfaces  التالية تستخدم في NET. للوصول للبيانات:

  • System.Data   جميع الكلاسات التي تستخدم للوصول إلى البيانات
  • System.Data.Common : الكلاسات التي تمت مشاركتها (أو تجاوزها) بواسطة مزودي البيانات بشكل فردي.
  • System.Data.Odbc 
  • System.Data.OleDb
  • System.Data.Oracle
  • System.Data.SqlClient
  • System.Data.SqlTypes : خاص أنواع البيانات SQL Server data types

في هذا الكتاب سيتم استخدام SQL Server

الكلاسات المهمة التي سيتم استخدامها في هذا الدروس:

  1. DataSet: صمم من أجل استخدامه في حالة عدم الإتصال. ويحتوي على مجموعة من DataTables التي ترتبط بالجدوال والعلاقات بين هذه الجداول.
  2. DataTable: يحتوي على عمود (DataColumn) واحد أو اكثر. عند استخدمه  سيحتوي بيانات التي عباره عن على الأقل صف واحد (DataRows).
  3. DataRow: مجموعة من القيم تشبه صفوف جداول.
  4. Data Column: هي كائن يحتوي على تعريف اسم ونوع البيانات الحقول.

الكلاسات لتحديد واتصال بالبيانات:

  1. SqlCommand: يستخدم للتعامل مع جمل SQL statement  و استدعاء الاجراءات Procedure calss
  2. SqlCommandBuilder يستخدم لانشاء اوامر SQL مثل INSERT, UPDATE, DELETE  من عبارة  SELECT
  3. SqlConnection يستخدم للاتصال بقاعدة بيانات
  4. SqlDataAdapter يستخدم للاحتفاظ ب اوامر select, insert, update, and delete التي تستخدم بعد ذلك للتعامل مع DataSet
  5. SqlDataReader: يستخدم لقراءة البيانات فقط..
  6. SqlParameter: لتعريف الباراميترات التي تستخدم في Procedures

التطبيق العملي:

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

لأنشاء قاعدة البيانات والجداول:

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-database-sql-server-transact-sql

الاتصال بقاعدة بيانات:

using System.Data.SqlClient;
string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
SqlConnection conn= new SqlConnection(source);
Conn.Open();

 zahersql هو الخادم الذي يحتوي على قاعدة البيانات BOOKS حيث اسم الكمبيوتر zaher . أما integrated security=SSPI يدل على أن نوع الامن للوصول لقاعدة البيانات هو Windows Authentication.

وافضل طريقة للاتصال هو:

try
{
     using (SqlConnection conn = new SqlConnection ( source ))
{
           // Open the connection
           conn.Open ( ) ;
          // Do something useful


         // Close it myself
              conn.Close ( ) ;
}
}
catch (Exception e)
{		// Do something with the exception here...
}

Command: هو عبارة عن نص يحتوي على عبارات SQL وممكن ان يحتوي على Procedure او اسم جدول الذي سيرجع كل أو جزء صفوف واعمدة جدول ما.

مثال:

using System.Data.SqlClient;
string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
 string Authortable = "SELECT * FROM Authors";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
 SqlCommand cmd = new SqlCommand(Authortable, conn);

 

كلاس Command يحتوي على خاصية اسمها CommandType التي تستخدم لتعريف الكلاس هل خو عبارة عن عبارة SQL  ام Procedure أو جدول كامل Full table . للتفصيل انظر الجدول التالي:

Example

Command Type

String select = “SELECT ContactName FROM Customers”;
SqlCommand cmd = new SqlCommand(select , conn);

 

Text (default)

SqlCommand cmd = new SqlCommand(“CustOrderHist”, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(“@CustomerID”, “QUICK”);

 

StoredProcedure

OleDbCommand cmd = new OleDbCommand(“Categories”, conn);
cmd.CommandType = CommandType.TableDirect;

 

TableDirect

تنفيذ الأمر Executing Commands:

بعد تعريف الCommand تحتاج إلى تنفيذه Exceute. هناك عدت طرق لتنفيذ الامر يعتمد على ماذا تريد أن يرجع الأمر:

  1. ExecuteNonQuery() لتنفيذ الأمر بدون ارجاع أي مخرجات.
  2. ExecuteReader() تنفيذ الأمر مع ارجاع من نوع IDataReader.
  3. ExecuteScalar() تنفيذ الأمر مع ارجاع قيمة واحدة.

مثال على استخدام ExecuteNonQuery

using System.Data.SqlClient;
string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
 string Authortable = "UPDATE  Authors SET FirstName=’JNA’  WHERE FirstName= ‘Ahmed’ ";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
 SqlCommand cmd = new SqlCommand(Authortable, conn);
int rowsReturned=cmd. ExecuteNonQuery();
Console.WriteLine("{0} rows returned.", rowsReturned);
conn.Close()

سترجع ExecuteNonQuery عدد الصفوف التي تأثرت بذلك الأمر.

 

مثال على استخدام  ExecuteReader:

using System.Data.SqlClient;

           string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
            string Authortable = "SELECT firstName, lastName FROM Authors";
            SqlConnection conn = new SqlConnection(source);
            conn.Open();
            SqlCommand cmd = new SqlCommand(Authortable, conn);
            SqlDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                Console.WriteLine("FirstName: {0} LastName: {1}" , reader[0] , reader[1]);
            }
            Console.ReadKey();

هذه الطريقة سترجع نوع بيانات data reader object بحيث هذا الobject ممكن ارجاع قيمه باستخدام التكرار مثل الظاهر في المثال اعلاه.  ونتائج البرنامج موضحة في الشكل التالي:

مثال على استخدام ExecuteScalar

using System.Data.SqlClient;

string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
string Authortable = "SELECT count(*) FROM Authors";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
 SqlCommand cmd = new SqlCommand(Authortable, conn);
Object o= cmd. ExecuteScalar ();
Console.WriteLine(o);

يستخدم فقط في حالة نتيجة عبارة SQL هي ارجاع قيمة واحدة فقط مثل هذا المثال فإن المخرج هو 4 وهي عدد صفوف جدول Authors.

عمليات السجلات:

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

  1. إضافة سجل

اذا اردنا اضافة مؤلف جديد اسمه Samear Hadi

string AddAuth = "INSERT INTO Authors(AuthorID,firstName,lastName) Values (@ID,@fname,@lname)";
            SqlCommand cmdAdd = new SqlCommand(AddAuth, conn);
            cmdAdd.Parameters.AddWithValue("ID", 5);
            cmdAdd.Parameters.AddWithValue("fname", "Sameer");
            cmdAdd.Parameters.AddWithValue("lname", "Hadi");
            try
            {                cmdAdd.ExecuteNonQuery();
                            }
            catch (SqlException ex)
            {                Console.WriteLine("Error- It can not Add ");            }

يجب ان يكون رقم المؤلف الجديد غير مستخدم في الجدول.

    2. حذف سجل:

اذا اردنا حذف المؤلف رقم 5

string Delet_Auth = "DELETE FROM Authors where AuthorID = @ID";
            SqlCommand cmddel = new SqlCommand(Delet_Auth, conn);
            cmddel.Parameters.AddWithValue("ID", 5);
            try
            {              cmddel.ExecuteNonQuery();                            }
            catch (SqlException ex)            {   
                          Console.WriteLine("Error-  ") ;
            }

    3. تعديل لقيم سجلات:

مثال: اذا اردنا تعديل اسم المؤلف  صاحب رقم 3 إلى Jna Zaher فإننا سنقوم بتنفيذ الأمر التالي:

string str = "UPDATE Authors SET  firstName =@fname, lastName=@lname WHERE AuthorID=@ID";
            SqlCommand cmd_Updat_Auth = new SqlCommand(str, conn);
            cmd_Updat_Auth.Parameters.AddWithValue("ID", "3");
            cmd_Updat_Auth.Parameters.AddWithValue("fname", "Jna");
            cmd_Updat_Auth.Parameters.AddWithValue("lname", "Zaher");
            try
            {   int rowsReturned=cmd_Updat_Auth.ExecuteNonQuery();
                Console.WriteLine("{0} rows returned.", rowsReturned);
            }
            catch (SqlException ex)
            {      Console.WriteLine("Error");            }

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

اذا اردنا ان نستخدم بعض الأدوات الواجهات الرسومية وجعلها تتفاعل وربطها مع قاعدة البيانات مثل Textboxesو Button وDataGridView

فإننا أولا سنحتاج إلى  SqlDataAdapter  و DataSet و Datable .

SqlDataAdapter 

عمل كـ جسر بين DataSetو SQL الخادم باسترداد وحفظ بيانات. عند SqlDataAdapterتعبئة DataSet، يقوم بإنشاء الجداول المطلوبة و أعمدة البيانات التي يتم إرجاعها إذا كانت غير موجود مسبقاً. ومع ذلك.

string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
  string Authortable = "SELECT * FROM Authors";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
SqlDataAdapter adap = new SqlDataAdapter(Authortable, conn);
DataSet ds = new DataSet();
adap.Fill(ds, "Authors");

حيث Fill هي دالة لتسترجع بيانات مخزنة في المصدر باستخدام عبارة SELECT

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

Datable هو كائن يمثل أحد جداول ال Dataset ، اي انك إذا اردت أن تقوم بعملية ما على احد هذه الجداول فعليك أن تنشئ كائن جديد من النوع DataTable

DataTable  records = ds.Tables["Authors"];

ربط القاعدة مع DataGridView

فمثلا في مرحلة تصميم الواجهات أضفنا dataGridView1 ونريدها تعرض جدول Author.

dataGridView1.DataSource = ds.Tables["Authors"];

حيث ds هو dataset من المثال السابق. الشكل التالي يبين النتائج:

التنقل بين السجلات وربط القاعدة بTextboxes

 ناخذ مثال الظاهر في الشكل التالي:

اولا نقوم بتصميم الواجهة.

افرض أن textBox1 هو مربع النص الذي يظهر الاسم الأول و textBox2 هو مربع النص الذي يظهر الاسم الأخير أما button1 هو First و button2 هو Next  و button3 هو Previous و button4 هو Last.

التطبيق:

  1. ربط textboxes  بقاعدة البيانات والجدول.
public partial class Form2 : Form
{ 
        private int rowindex = 0;   // تم استخدامه ليكون مساعد ومحدد لرقم سجل الذي تم انتقال إليه 
private void Form2_Load(object sender, EventArgs e)
        {
    	string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
  string Authortable = "SELECT * FROM Authors";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
SqlDataAdapter adap = new SqlDataAdapter(Authortable, conn);
DataSet ds = new DataSet();
adap.Fill(ds, "Authors");   	
records = ds.Tables["Authors"];
//تعبئه مربع النصوص بأول سجل من جدول المؤلف إذا احتوى على سجلات
            if (records.Rows.Count > 0)		
/* records.Rows.Count  تساوي 0 اذا كان جدول Authors فارغ*/
            {   textBox1.Text = records.Rows[0]["firstName"].ToString();
                textBox2.Text = records.Rows[0]["lastName"].ToString();
                        }

    2.  ازار التنقل :

  • First: الانتقال إلى السجل الأول
private void button1_Click(object sender, EventArgs e)
        {    if (records.Rows.Count > 0 )
            { textBox1.Text = records.Rows[0]["firstName"].ToString();
                textBox2.Text = records.Rows[0]["lastName"].ToString();
                rowindex = 0;
            }
        }
  • Next: للتنقل إلى السجل التالي.
private void button2_Click(object sender, EventArgs e)
     {      rowindex++;
            if (records.Rows.Count > 0 && rowindex < records.Rows.Count)
            {  textBox1.Text = records.Rows[rowindex]["firstName"].ToString();
                textBox2.Text = records.Rows[rowindex]["lastName"].ToString();
            }
            if (rowindex > records.Rows.Count-1)  // من أجل أن لا يتعدى رقم السجل الأخير
                rowindex = records.Rows.Count-1;
        }
  • Previous: للانتقال الى السجل السابق
private void button3_Click(object sender, EventArgs e)
        {        rowindex--;
            if (records.Rows.Count > 0 && rowindex >=0)
            {  textBox1.Text = records.Rows[rowindex]["firstName"].ToString();
                textBox2.Text = records.Rows[rowindex]["lastName"].ToString();
               }
            if (rowindex < 0)    // من اجل أن لا يسبق أول سجل
                rowindex = 0;
        }
  • Last: الانتقال إلى السجل الأخير
private void button4_Click(object sender, EventArgs e)
        {  if (records.Rows.Count > 0)
            {         textBox1.Text = records.Rows[records.Rows.Count-1]["firstName"].ToString();
                    textBox2.Text = records.Rows[records.Rows.Count-1]["lastName"].ToString();
                   rowindex = records.Rows.Count-1;
                 }
        }

البحث في جداول:

كيفية البحث عن المؤلفين الذين يحتوي اسمهم الأخير على كلمة معينة تكتب في textBox1. اولا تصمم الواجهه في الشكل التالي:

 

ثم نكتب الكود التالي في حدث TextChanged لtextBox1:

private void textBox3_TextChanged(object sender, EventArgs e)
        {  string st = "SELECT * FROM Authors WHERE  lastName LIKE '%" + textBox3.Text + "%' ";
            SqlDataAdapter  searchadap = new SqlDataAdapter(st, conn);
            DataSet ds1 = new DataSet();
            searchadap.Fill(ds1);
            dataGridView1.DataSource = ds1.Tables[0];
        }

الربط أكثر من جدول وعرضها في dataGridView1

string source = "server=zaher\\zahersql ;integrated security=SSPI;database=BOOKS";
string Book = "SELECT title, publisherName, edtionNumber, copyright, price FROM Titles ,publishers 
    		WHERE Titles.pubID = publishers.pubID";
 SqlConnection conn= new SqlConnection(source);
Conn.Open();
SqlDataAdapter adap = new SqlDataAdapter(Book, conn);
DataSet ds = new DataSet();
adap.Fill(ds );
dataGridView1.DataSource = ds.Tables[0];

المراجع

[1]      S. Robinson, C. Nagel, J. Glynn, M. Skinner, K. Watson, and B. Evjen, Professional C#. 2004.

[2]      Harvey M. Deitel, P. J. Deitel, T. R. Nieto, C. H. Yaeger, M. Zlatkina, and J. Listfield, C#: How to Program. 2002.

[3]      Microsoft, “msdn.microsoft.com.” .

​ ​​

0
إعجاب
6885
مشاهدات
1
مشاركة
2
متابع

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

imad:

مفيد جدا شكرا اخي الكريم وكثر الله الرجال امثالك

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !