Data Access Layer :
في التطبيقات الجدية ، لا يتم وضع الكود مع المظهر مع سيناريو وعمليات البرنامج اضافة لطبقة البيانات، بل يتم فصل كل منها في طبقة منفصلة وهو ما يعرف باسم Layers ، لمعرفة المزيد عن هذا الموضوع يمكنك مراجعة الرابط التالي :
http://www.al-asiri.com/ShowRecord.aspx?Action=Open&id=cefa426c-d9e0-4625-a66b-87fd6082ff89
وهناك تطبيق ايضاً هنا :
http://vb4arb.com/vb/showthread.php?824
في هذه المرحلة ، سنحاول عمل data layer تكون خاصة بالتعامل مع قواعد البيانات لتحقيق نقطتين مهمتين :
- اعادة استخدامها اكثر من مرة .
- في حالة وجود خطأ يتم تحديد مصدره بسهولة ، وفي حالة التعديل لا يتم التعديل سوى على هذه الطبقة .
وفي هذه الحالة لن يتطرق مبرمج اي جزء من البرنامج إلى كيفية الاتصال بقاعدة البيانات ، حيث ان كل ما لديه هي مجموعة من الدوال للاتصال والحذف والتعديل وكل العمليات التي يريدها مع بارميترات مناسبة دون التدخل في كيفية الاتصال بقواعد البيانات تماماً .
يمكنك عمل هذه الطبقة بعدة طرق ، ابسطها استخدام بعض البرامج الجاهزة التي تقوم بهذه العملية وتقوم بعمل استخراج لهذه ال layer حسب لغة البرمجة التي تحددها ، ايضاً يوفر لك الدوت نت طريقة لهذه العملية ، الطريقة الثانية هي الطريقة اليدوية ...
في العجالة التالية سنتعرف على مثال بسيط لهذه العملية من اجل الموظفين ، يمكن تطبيق نفس المفاهيم على البرامج الجدية لاحقا .
1- عمليات فتح واغلاق قواعد البيانات :
C#:
كود :
[SIZE=3]private SqlConnection cn = new SqlConnection();
public void OpenConnection(string connectionString)
{
cn.ConnectionString = connectionString;
cn.Open();
}
public void CloseConnection()
{
cn.Close();
}[/SIZE]
vb.net:
كود :
Private cn As New SqlConnection()
Public Sub OpenConnection(ByVal connectionString As String)
cn.ConnectionString = connectionString
cn.Open()
End Sub
Public Sub CloseConnection()
cn.Close()
End Sub
2- سيناريو عملية الحذف .
في هذه العملية سنتيح للمستخدم حذف الموظف باسمه ، او حذف الموظف برقمه ، او حذف الموظف مثلاً بدلالة العمر وبعدة اختيارات سواء اكبر او اقل او يساوي مثلاً مع استخدام مبدأ ال OverLoading ومبدأ عمل Enums ايضاً واللذان تم شرحهما في دروس سابقة .
*** لاحظ ان مهمتك في هذه المرحلة هي عمل كل الدوال التي يمكن استخدامها في البرنامج تحت اي ظرف من الظروف :
C#:
كود :
[SIZE=3]public void DeleteEmployee(int id)
{
string sql = string.Format("Delete from Employee where ID = {0}",
id);
using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
{
try
{
cmd.ExecuteNonQuery();
}
catch(SqlException ex)
{
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}[/SIZE]
[SIZE=3]public void DeleteEmployee(string name)
{
string sql = string.Format("Delete from Employee where [First Name] = '{0}'",
name);
using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
{
try
{
cmd.ExecuteNonQuery();
}
catch(SqlException ex)
{
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}[/SIZE]
[SIZE=3]enum deletecondition
{
morethan=0,
lessthan=1,
equal=2
}[/SIZE]
[SIZE=3]public void DeleteEmployee(int age,deletecondition delcondition)
{
string sql="";
if(delcondition == deletecondition.morethan)
sql = string.Format("Delete from Employee where age > {0}",age);
else if(delcondition == deletecondition.lessthan)
sql = string.Format("Delete from Employee where age < {0}",age);
else
sql = string.Format("Delete from Employee where age = {0}",age);[/SIZE]
[SIZE=3]using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
{
try
{
cmd.ExecuteNonQuery();
}
catch(SqlException ex)
{
Exception error = new Exception("some error occures: ", ex);
throw error;
}
}
}[/SIZE]
vb.net:
كود :
[SIZE=3]Public Sub DeleteEmployee(ByVal id As Integer)
Dim sql As String = String.Format("Delete from Employee where ID = '{0}'", id)
Using cmd As New SqlCommand(sql, Me.sqlCn)
Try
cmd.ExecuteNonQuery()
Catch ex As SqlException
Dim [error] As New Exception("some error occures: ", ex)
Throw [error]
End Try
End Using
End Sub [/SIZE]
[SIZE=3]Public Sub DeleteEmployee(ByVal name As String)
Dim sql As String = String.Format("Delete from Employee where [First Name] = '{0}'", name)
Using cmd As New SqlCommand(sql, Me.sqlCn)
Try
cmd.ExecuteNonQuery()
Catch ex As SqlException
Dim [error] As New Exception("some error occures: ", ex)
Throw [error]
End Try
End Using
End Sub[/SIZE]
[SIZE=3]enum deletecondition
{
morethan=0,
lessthan=1,
equal=2
}[/SIZE]
[SIZE=3]Public Sub DeleteEmployee(ByVal age As Integer, ByVal delcondition As deletecondition)
Dim sql As String = ""
If delcondition = deletecondition.morethan Then
sql = String.Format("Delete from Employee where age > {0}", age)
ElseIf delcondition = deletecondition.lessthan Then
sql = String.Format("Delete from Employee where age < {0}", age)
Else
sql = String.Format("Delete from Employee where age = {0}", age)
End If
Using cmd As New SqlCommand(sql, Me.sqlCn)
Try
cmd.ExecuteNonQuery()
Catch ex As SqlException
Dim [error] As New Exception("some error occures: ", ex)
Throw [error]
End Try
End Using
End Sub [/SIZE]
3- سيناريو عمليات الاضافة والتعديل :
بنفس الطريقة يمكن التعديل بعدة خيارات او الاضافة بعدة طرق .
بالنسبة لعملية الاضافة سنجبره على ادخال الاسم الأول والأخير فقط .
والتعديل ينبغي أيضاً أن يكون بنفس الصورة ، ولكن منعاً للاطالة سنعدل بدلالة الرقم الاسم الأول فقط .
C#:
كود :
[SIZE=3]public void InsertEmployee(string fname, string lname, int age)
{
// Format and execute SQL statement.
string sql = string.Format("Insert Into Employee_info" +
"([First Name], [Last Name]) Values" +
"('{0}', '{1}')",fname, lname);[/SIZE]
[SIZE=3]using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
{
cmd.ExecuteNonQuery();
}
}[/SIZE]
[SIZE=3]public void UpdateEmployee(int id, string newFirstName)
{[/SIZE]
[SIZE=3]string sql =
string.Format("Update Employee Set [First Name] = '{0}' Where ID = '{1}'",
newFirstName, id);
using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
{
cmd.ExecuteNonQuery();
}
}[/SIZE]
vb.net:
كود :
[SIZE=3]Public Sub InsertEmployee(ByVal fname As String, ByVal lname As String, ByVal age As Integer)
' Format and execute SQL statement.
Dim sql As String = String.Format("Insert Into Employee_info" + "([First Name], [Last Name]) Values" + "('{0}', '{1}')", fname, lname)
Using cmd As New SqlCommand(sql, Me.sqlCn)
cmd.ExecuteNonQuery()
End Using
End Sub [/SIZE]
[SIZE=3]Public Sub UpdateEmployee(ByVal id As Integer, ByVal newFirstName As String)
Dim sql As String = String.Format("Update Employee Set [First Name] = '{0}' Where ID = '{1}'", newFirstName, id)
Using cmd As New SqlCommand(sql, Me.sqlCn)
cmd.ExecuteNonQuery()
End Using
End Sub [/SIZE]
4- سيناريو عمليات البحث .
قبل البدء في سيناريو عملية البحث ، نود أن نشير إن الدوال السابقة ينقصها شيء هام وهي عملية ال Parameters لتلافي المشاكل الناتجة عن ال Sql Injection ، لكن كانت الامثلة السابقة للتوضيح فقط ، في عملية البحث الآن سنطبق ما تعلمناه لحل هذه المشكلة .
سنجرب عملية بحث واحدة عن الاسم الأول والأخير للأشخاص برقم ID معين ، لا تنسى أنك مطالب في Data Layer بعمل كل الطلبات التي قد يحتاجها مبرمج عمليات البرنامج لكي لا يحتاج لكتابة حتى جملة استعلام واحدة .
سنقوم اولاً بعمل Stored Procedure :
كود :
[SIZE=3]CREATE PROCEDURE GetFirstNameByID
@id int,
@fName char(10) output
AS
SELECT @fName=[First Name] from Employee_info where ID > @id[/SIZE]
ومن ثم نقوم نعرف الدالة الخاصة بعملية البحث بالشكل التالي :
C#:
كود :
[SIZE=3]public string SelectName(int id)
{[/SIZE]
[SIZE=3]using (SqlCommand cmd = new SqlCommand("GetFirstNameByID", cn))
{
cmd.CommandType = CommandType.StoredProcedure;[/SIZE]
[SIZE=3]SqlParameter param = new SqlParameter();
param.ParameterName = "@id";
param.SqlDbType = SqlDbType.Int;
param.Value = ID;
param.Direction = ParameterDirection.Input;
cmd.Parameters.Add(param);[/SIZE]
[SIZE=3]param = new SqlParameter();
param.ParameterName = "@fName";
param.SqlDbType = SqlDbType.Char;
param.Size = 10;
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);[/SIZE]
[SIZE=3]cmd.ExecuteNonQuery();[/SIZE]
[SIZE=3]return cmd.Parameters["@fName"].Value.ToString();
}
return carPetName;
}[/SIZE]
vb.net:
كود :
myDataLayer example=new myDataLayer();
example.OpenConnection(myconnectionstring);
example.DeleteEmployee(10);
example.DeleteEmployee("Ahmed");
--- لاحقاً يمكنك فصل ال DataLayer حتى في dll منفصلة لضمان تشغيلها مع اكثر من تطبيق ، في الاستخدام لاحقاً وعلى افتراض ان الفئة Class لطبقة البيانات DataLayer تحمل الاسم myDataLayer ، ولتطبيق عملية مثل الحذف كل المطلوب منك هو سطرين مثل الآتي :
C#:
كود :
[SIZE=3]Dim example As New myDataLayer()
example.OpenConnection(myconnectionstring)
example.DeleteEmployee(10)
example.DeleteEmployee("Ahmed") [/SIZE]
vb.net:
Dim example As New myDataLayer() example.OpenConnection(myconnectionstring) example.DeleteEmployee(10) example.DeleteEmployee("Ahmed")
وفقط !!!
وبنفس النظام لو كانت dll قم باستيرادها في برنامجك ثم قم باستخدامها بنفس الطريقة .
لو لاحظت ، بهذه الطريقة اصبح المبرمج لسيناريو البرنامج ولباقي عملياته بعيداً كل البعد عن قواعد البيانات ، كما ان تقسيم العمل أصبح أوضح وبالتالي اصبح بالامكان تدارك المشاكل بصورة أوضح .