الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشروع قاعدة الوصول للبيانات Data Access Base

بدأه HelloWorld في 9 أكتوبر 2010 · 6 رد · 2,767 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

مقدمة

الكثير منا يعرف بأن هناك معمارية لبناء التطبيقات تدعى N-Tier Architecture وفكرتها تقوم على مبدأ فصل أجزاء المشروع البرمجي إلى عدة طبقات ويتفاوت عدد هذه الطبقات حسب نوع التطبيق وحجمه ولكن في الأعم الأغلب هناك ثلاثة طبقات أساسية هي: Data Access Layer و Business Layer و Presentation Layer.

فكرة المشروع

فكرة المشروع هي بناء القاعدة الأساسية المساعدة لطبقة الوصول للبيانات ، وللتوضيح أكثر تحتوي طبقة الوصول للبيانات Data Access Layer على جزئين أساسيين:

أولاً: جزء يتعلق بالتعامل مع مختلف أنواع قواعد البيانات ومزوديها في بيئة الدوت نت MS .Net Framework ووظيفته الأساسية هي تنظيم عملية الاتصال بقاعدة البيانات وتنفيذ الاستعلامات.

ثانياً: الجزء الآخر يقوم باستخدام الجزء الأول الذي تحدثنا عنه عبر تمرير الاستعلامات المطلوبة Queries واستلام نتائج هذه الاستعلامات، وهو يختلف باختلاف نوع التطبيق وقاعدة البيانات المرتبطة به والجداول التي تحتويها قاعدة البيانات.

ما نود عمله هو الجزء الأول وهو أساس فكرة المشروع الذي سنسميه قاعدة الوصول للبيانات Data Access Base ، وحاليا المشروع يعتمد على قواعد بيانات SQL Server 2005 وبالإمكان تطوير ليشمل قواعد البيانات الأخرى.

المزايا العامة للمشروع:

1) إعادة الاستخدام Reusability: يمكن استخدام هذه القاعدة عند البدء بأي مشروع، بدون إعادة كتابة الأكواد وتكرارها.

2) سهولة الاستخدام Ease of Use: الكود المستخدم سهل الاستخدام وواضح (للمبرمج طبعا) وخالٍ من التعقيد والتكرار.

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

4) الأداء Performance: سرعة تنفيذ الاستعلامات عبر الوصول المباشر لقاعدة البيانات.

5) المرونة Flexibility: القدرة الكبيرة للمبرمج في التحكم بأجزاء البرنامج المختلفة بدون الحاجة لتغيير الكود.

6) الحجم الصغير Small Size: حجم الكود صغير جدا.

7) الأمن Security: ضمان مستوى معقول من الأمن على البيانات عند تمرير الاستعلامات.

أدوات التطوير Development Tools

مشروع Data Access Base عبارة عن مكتبة فئاتWindows Class Library مكتوبة بلغة C# من خلال برنامج Microsoft Web Developer 2010 Express وهو برنامج مجاني من شركة مايكروسوفت.

قاعدة البيانات Database

يمكن استخدام أي قاعدة بيانات من نوع SQL Server 2005 Or 2008

كيفية الاستخدام

المكان الطبيعي لإضافة هذه المكتبة ضمن معمارية تعدد الطبقات N-Tier Architecture هي طبقة البيانات Data Layer لأن هذه الطبقة سوف تقوم باستخدام المكتبة التي قمنا بعملها وفي الحقيقة إذا إردنا أن ننظر من منظار هندسة البرمجيات ستكون هذه المكتبة هي الواسطة بين قاعدة البيانات وبين Data Layer الخاصة بأي مشروع. ولكن يمكن استخدامها مباشرة في أي تطبيق حتى لو لم يكن يعتمد معمارية تعدد الطبقات وفي هذه الحالة سيتم إضافة هذه المكتبة مباشرة في تطبيق الويب Web Application أو في تطبيق الويندوز Windows Application وسيتم استخدام هذه الطريقة في عرض أمثلة استخدام هذه المكتبة.

خطوات الاستخدام

أولاً:

كما قلنا سابقا المشروع عبارة عن مكتبة فئات Windows Class Library يمكن إدراج هذه المكتبة ضمن أي مشروع Project عبر الوظيفة Add Reference الموجودة تحت القائمة Project أو بالضغط على يمين الفأرة على References.

ثانياً:

إضافة نص الاتصال ConnectionString الخاص بقاعدة البيانات في ملف Web.Config ويقع تحت قسم ConnectionStrings ، ويمكن إضافة أكثر من نص اتصال وذلك في حالة كان التطبيق يحتاج للاتصال بأكثر من قاعدة بيانات واحدة.

<connectionStrings>
    <add name="MySchool_DB" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MySchool;Persist Security Info=True;User ID=sa; Password=12345" providerName="System.Data.SqlClient"/>
  </connectionStrings>

ثالثاً:

إضافة مفتاح جديد في تحت قسم AppConfig في نفس الملف Web.cofig وذلك باسم ConnectionStringName وذلك لتحديد قاعدة البيانات الافتراضية، والفائدة من إضافة هذا المفتاح هي امكانية تغيير قاعدة البيانات الافتراضية بسهولة في حال وجود أكثر من قاعدة بيانات وعادة ما يحدث ذلك في فترات التطوير حيث تستخدم قاعدة بيانات ومن ثم يتم التغيير لقاعدة البيانات أخرى بعد انتهاء هذه الفترة.

  <appSettings>	
    <add key="ConnectionStringName" value="MySchool_DB"/>
  </appSettings>

رابعاً:

في هذا المثال نستعرض طريقة عمل مكتبة (قاعدة الوصول للبيانات) ، في المثال التالي سوف نقوم باستخدام قاعدة الوصول للبيانات Data Access Base مباشرة في تطبيق ويب Web Application تحت الحدث Page_Load ، اترك لكم قراءة الكود:

protected void Page_Load(object sender, EventArgs e)
{
   SqlServerDb schoolDb = new SqlServerDb();	
   SqlDataReader reader = schoolDb.ExecuteReader("SELECT * FROM Students");	

   if (reader.HasRows)
   	{
        	while (reader.Read())
                {
                    Response.Write(reader[0] + "-" + reader[1] + "<br/>");
                }
}

       reader.Close();
}

في المثال السابق نقطتين مهمتين الأولى تتعلق بالسطر الاول:

SqlServerDb schoolDb = new SqlServerDb();

هذا السطر يقوم بعمل نموذج جديد من الفئة SqlServerDB والذي بشكل افتراضي يقوم باعتبار أن النص الافتراضي لقاعدة البيانات هو النص الذي حددنا اسمه ConnectionStringName ولذلك لا حاجة لذكر أي شيء يتعلق بنص الاتصال أو بقاعدة البيانات.

أما السطر التالي:

SqlDataReader reader = schoolDb.ExecuteReader("SELECT * FROM Students");

فيتم فيه استدعاء الدالة ExecuteReader وتمرير الاستعلام SQL Query لتنفيذه واستلام نتيجة الاستعلام في المتغير reader، بقية الأسطر واضحة ولكن فقط أردت الإشارة بأن من المهم استدعاء الدالة Close بعد الانتهاء من قراءة البيانات.

امثلة أخرى:

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

schoolDb.ExecuteNonQuery("INSERT INTO Students (StudentID, StudentName) VALUES (1,'Ali');");

مثال آخر:

object objCount = schoolDb.ExecuteScalar("SELECT COUNT(*) FROM Students");

هناك دالة أخرى خاصة باسترجاع البيانات بهيئة DataSet ونستخدمها بالصورة التالية:

DataSet dsStudents = schoolDb.GetDataSet("SELECT * FROM Students");

تمرير الوسائط للاستعلامات

عادة ما يتم استخدام الوسائط Parameters لتمريرها للاستعلامات، هناك طريقتنان لعمل ذلك الطريقة الاولى وهو تمرير المتغيرات مباشرة إلى الاستدعاء ولكن هذه الطريقة غير آمنة نظرا لإمكانية حدوث اختراق من نوع SQL Injection ، أما الطريقة الثانية هي تمرير الوسائط SqlParameters ولكن يعيب هذه الطريقة أنها تحتاج لكتابة الكثير من الأكواد وتكرارها في حال كتابة أي استدعاء بالطريقة التقليدية فيجب تمريره إلى CommandObject ثم اضافة كل وسيط على حدة وتفاصيل أخرى. من أهم مزايا استخدام هذه المكتبة هي الطريقة السهلة والمختصرة في تطبيق هذا الأمر، المثال التالي يوضح ذلك:

ArrayList arParameters = new ArrayList();	

arParameters.Add(new SqlParameter("@ClassRoomID", txtClassRoom.Text));

SqlDataReader reader = schoolDb.ExecuteReader("SELECT * FROM Students Where ClassRoomID = @ ClassRoomID", arParameters);

بالمثال السابق نستطيع تجاوز مشكلة عدم القدرة على تمرير SqlParameters كمجموعة Collection نظرا لبعض الصعوبات التقنية المرتبطة بطريقة تطوير هذه العناصر ضمن إطار عمل الدوت نت .Net Framework وهي كثيرا ما واجهتني شخصيا لكني مؤخرا تغلبت عليها عبر تمرير ArrayList يضم قائمة الوسائط وهو اسهل بكثير في التعامل من ال Array العادي في تمرير الوسائط وفي طريقة الاضافة حيث أنه من النوع ال Dynamic.

إشارة أخرى هي أن كل دالة من الدوال التي ذكرتها سابقا يمكن تمرير الوسائط إليها بالطريقة المذكورة كما يمكن استخدامها بدون تمرير وسائط، أما تمرير الوسائط بشكل مباشر فهي كما ذكرت طريقة غير آمنة إذا كانت هذه الوسائط مرتبطة بمدخلات المستخدم User Inputs.

استخدام قاعدة بيانات أخرى

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

SqlServerDb schoolDb = new SqlServerDb("OrdersDB");

معالجة الاستثناءات Exceptions

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

try
            {
                SqlServerDb schoolDb = new SqlServerDb();
                ArrayList arSqlParameters = new ArrayList();

                arSqlParameters.Add(new SqlParameter("@StudentID", 2));

                SqlDataReader reader = schoolDb.ExecuteReader("SELECT * FROM Students Where StudentID = @StudentID", arSqlParameters);

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        Response.Write(reader[0] + "-" + reader[1] + "<br/>");
                    }
                }

                reader.Close();
            }
            catch (DataAccessException exp)
            {
                Response.Write("Error Message: " + exp.Message);
            }

برمجة المشروع

ربما يتفاجأ من يقوم بالاطلاع على برمجة المشروع من صغر حجم المشروع، وربما يعتبره عمليا ليس مشروع حيث لا يتعدى عدد أسطر البرمجة فيه 250 سطر، وجهة نظري هي أن أهمية الفكرة وفائدتها والتطبيق العملي لهذه الفكرة هي العوامل التي تحدد نجاح المشروع من عدمه وليس فقط عدد أسطر البرمجة فيه. هناك الكثير من التطويرات والإضافات الممكنة لهذا المشروع فضلا عن الاصلاحات والتعديلات الممكن تطبيقها عليه ولكني فضلت عدم التأخر في طرح هذا المشروع، ما أتمناه هو أن استمع إلى وجهة نظر المبرمجين وتعليقاتهم حول المشروع، ولي عودة بعد ذلك إن شاء الله، يمكنكم تنزيل ملف المشروع لوحده واستخدامه وهو DataAccessBase.dll وطبعا لمن يحب الاطلاع على برمجة المشروع ملفات المشروع مرفقة كذلك.

DataAccessBase.zip

DataAccessBase_SourceCode.zip

2
#2

مرة أخرى سلامٌ من الله عليكم...

قريبا إن شاء الله سوف أضيف مجموعة من التحسينات والإضافات الجديدة لمشروع Data Access Base والتي سوف تجعل هذه المكتبة البرمجية وهذا المشروع أقوى وأقوى ويمكن الاعتماد عليه بصورة جدية في أي مشروع يقوم به المبرمج. علما بأن هذه الإضافات لن تؤثر على البنية البرمجية للمشروع التي تم شرحها ولا على التوافقية Compatibility مع الاصدار الاول.

ما زلت أرحب بأي استفسار أو اقتراح أو ملاحظة بهذا الخصوص واللقاء قريب إن شاء الله.

#3

الله يعطيك العافيه

سؤال بخصوص تمرير الـ Parameters

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

وإن شاء الله يتطور المشروع وراح يستفيد منه أشخاص كثر وانا اولهم ( :

وجزاك الله خيرا والله يوفقك في طموحك وإن شاء الله أقدر أساهم معك في مشاريعك <<<< على قدي

#4

نعم يمكنه كتابتها وسوف تمرر إلى أي استعلام Query بصورة آمنة Secure لأي نوع من أنواع الاستعلامات سواء كان للإضافة أو التحديث أو لقاعدة البيانات، وهناك تكمن القوة في السهولة والأمن معاً.

#5

مرة أخرى أعود لكم مع بعض التطويرات الإضافية لهذا المشروع، باختصار هذه هي قائمة الإضافات:

1) دعم إجراءات قواعد البيانات Stored Procedures : يمكن الآن الاستفادة من هذه الميزة عبر ذكر اسم الإجراء Stored Procedure الموجود في قاعدة البيانات وتحديد النوع عبر كتابة CommandType.StoredProcedure، وفي حال كنت تحتاج لتمرير بعض الوسائط SqlParameters فبإمكانك تمريرها كما تم التوضيح سابقا وإلا فلا حاجة لتمرير شيء آخر، ننتقل مباشرة إلى المثال:

SqlServerDb schoolDb = new SqlServerDb();
            DataSet dsStudents = schoolDb.GetDataSet("USP_STUDENTS_LIST", CommandType.StoredProcedure);

شيء آخر يجب ذكره أن دعم الإجراءات StoredProcedures تم تطبيقه على كل الدوال والوظائف الموجودة مثل ExecuteReader فيمكنه استعماله معها.

2) دعم XML Reader: أصبح بالإمكان الحصول على نتائج الاستعلامات بهيئة xml وذلك عبر إضافة الدالة ExecuteXmlReader والمثال التالي يوضح ذلك:

SqlServerDb schoolDb = new SqlServerDb();
            XmlReader xmlReaderObject = schoolDb.ExecuteXmlReader("Select * From Students For Xml Auto, XMLDATA");

3) تحديث الـ DataSets: تعرفون أن الدالة الموجودة GetDataSet يمكنها جلب نتائج الاستعلامات بصورة DataSet ولكن هل فكرتم أن بالإمكان عمل التغييرات اللازمة على DataSet ومن ثم إرسالها مباشرة إلى قاعدة البيانات؟، أصبح ذلك ممكنا مع الدالة الجديدة UpdateDataSet وهذا مثال يوضح استخدامها:

            SqlServerDb schoolDb = new SqlServerDb();
            string strQuery = "Select * From Students";
            DataSet dsStudents = schoolDb.GetDataSet(strQuery);

            string strStudentName = dsStudents.Tables[0].Rows[0][1].ToString();

            dsStudents.Tables[0].Rows[0].BeginEdit();
            dsStudents.Tables[0].Rows[0][1] = strStudentName + " ABC";
            dsStudents.Tables[0].Rows[0].EndEdit();

            schoolDb.UpdateDataSet(strQuery, dsStudents);

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

DataAccessBase2.zip

DataAccessBase_SourceCode_2.zip

#6

مرة أخرى، سلامٌ من الله عليكم ورحمة...

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

1) ما هي المزايا التي بإمكانها أن تنقل هذا المشروع نقلة نوعية من حيث الفكرة؟

2) ما هي الإضافات والتطويرات الممكنة للمشروع بشكله الحالي؟

3) ما الذي أعجبك في المشروع؟

4) ما هو تقييمك للمشروع من ناحية الاحترافية في كتابة الكود (مبتدىء، متوسط،خبير)؟

5) ما هي طريقتك حاليا في كتابة الكود الخاص بالوصول لقاعدة البيانات؟

بانتظاركم :)

تم تعديل هذه المشاركة بواسطة HelloWorld في 26 أكتوبر 2010 في 16:15

#7

باعتقادي بأن هذا المشروع وصل لمرحلة متقدمة بالنظر إلى الهدف الذي وضع من أجله، ويمكن الاستفادة منه بصورة عملية والبناء عليه، ولذلك بالنسبة لي، لقد انتهيت من مشروع قاعدة الوصول للبيانات حسب المدة الزمنية المحددة وقائمة الخصائص والمزايا Features التي وضعتها للمشروع.

ألقاكم في القادم في الأيام...وشكرا لكم

مواضيع مشابهة