تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مدخل عملي لـ N-Tier - التطبيقات المُتعددة الطبقات
#1
بداية أحب أنوه أنه صاحب الموضوع هو الأخ أبو عابد وأنا نقلت الموضوع لما له من أهميه وشرح مميز
الرابط الأصلى للموضوع لعى منتدى فيجوال بيسك العرب
http://vb4arab.com/vb/showthread.php?t=10969

ندخل فى الموضوع


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


ربما سمع البعض منكم عن تصميم التطبيقات بطريقة الطبقات N-Tier .
إن كنت لم تسمع عنها فأنصحك بقراءة مقال الأخ تركي العسيري على هذا الرابط
http://www.al-asiri.com/ShowRecord.a...b-87fd6082ff89

لقد أجاد كعادته في إعطاء نبذة عن التطبيقات متعددة الطبقات . ثم شرع في مثال لشرح تلك الفكرة .


هنا أحاول طرح الفكرة بشكل كامل بإذن الله و الله الموفق .


متطلبات العمل :
1- الإلمام بتصميم الكائنات .
2- الإلمام باستخدام قواعد البيانات SQL Server 2000 .



سنحاول في هذا الموضوع بناء تطبيق صغير هو : دليل هاتف (آمل ألا تشعر بالغثيان مثلي من هذا المثال) .
لن تجد هنا المثالية في الطرح أو المستوى العلمي في السرد ، و لكن كلي أمل أن تجد نتاج تجارب عملية أرجو من الله أن تكون مفيد لكم لفتح آفاق جديدة في البرمجة بـ OOP مع N-Tier .




ندخل في الموضوع :
تطبقنا هو دليل هاتف ، اسم الشخص و بيانات الاتصال به فقط .


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

أكرر الكائنات و ليست الجداول أو الشاشات .

لماذا نبدأ في الكائنات ؟
لست أدعى حصر الأسباب ولكن دعني أقول :

الأول : لأنها تقع في طبقة الأعمال (أرجع لمقال تركي لتعلم ما معنى طبقة الأعمال) و التي هي الأساس للتطبيق.

قد تجد تطبيقات بدون طبقة عرض كالـ Service .
أو تطبيقات بدون طبقة البيانات كالآلة الحاسبة .
ولكن لا يتصور برنامج صمم بطريقة N-Tier لا يوجد به طبقة للأعمال .


الثاني : و لأن طبقة الأعمال هي الطبقة الوسيطة بين طبقة العرض وطبقة البيانات فلا يتم الاتصال بين طبقة العرض و البيانات إلا بواسطة طبقة الأعمال ، ولهذا فهي تشمل أغلب جوانب التطبيق .



نعود لتطبيقنا السابق .
برأيي أننا نحتاج لـ
1- كائن شخص ، و يحتوى على صفات مثل :
a. الاسم
b. العمر
c. مكان الإقامة
d. العمل
2- كائن رقم الاتصال ، ويحتوى على صفات مثل :
a. النوع : خلوي ، سكني ، تجاري ، بيجر
b. رقم : نضع فيه الرقم .

حسناً عرفنا الآن خصائص الكائنين ، ولكن ماذا عن سلوكوهما ؟
1- كائن شخص ، يحتاج لـ
a. وظيفة للحفظ
b. وظيفة للعرض
c. وظيفة للحذف
d. وظيفة للتعديل
2- كائن الرقم .
a. وظيفة للحفظ
b. وظيفة للعرض
c. وظيفة للحذف
d. وظيفة للتعديل

في المشاركة التالية سنحول هذا الكلام إلى كلاسات بإذن واحد أحد .


والسلام عليكم ورحمة الله وبركاته .
__________________
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#2
نبدأ في إنشاء طبقة الأعمال :

[ATTACH=CONFIG]500[/ATTACH]


[ATTACH=CONFIG]501[/ATTACH]

[ATTACH=CONFIG]502[/ATTACH]

ثم نكتب هذا الكود داخل الفئة Person

نبدأ بتعريف المتغيرات الداخلية

PHP كود :
Public Class Person

#Region "Private Variables"
    
Private _ID As Integer 0
    
Private _Name As String ""
    
Private _Age As Integer 0
    
Private _Area As String ""
    
Private _Job As String ""
#End Region 

ثم نكتب الخصائص

PHP كود :
#Region "Properties"
    
Property ID() As Integer
        Get
            
Return _ID
        End Get
        Set
(ByVal value As Integer)
            
_ID value
        End Set
    End Property
    Property Name
() As String
        Get
            
Return _Name
        End Get
        Set
(ByVal value As String)
            
_Name value
        End Set
    End Property
    Property Age
() As Integer
        Get
            
Return _Age
        End Get
        Set
(ByVal value As Integer)
            
_Age value
        End Set
    End Property
    Property Area
() As String
        Get
            
Return _Area
        End Get
        Set
(ByVal value As String)
            
_Area value
        End Set
    End Property
    Property Job
() As String
        Get
            
Return _Job
        End Get
        Set
(ByVal value As String)
            
_Job value
        End Set
    End Property
#End Region 

ثم نكتب الإجراء المشيد للفئة :

PHP كود :
#Region "Initialize Sub's"

    
Sub New()

    
End Sub

#End Region 

ثم نكتب الوظائف الرئيسية للفئة ، كما قلنا إضافة حذف تعديل (أما العرض فلاحقاً)


PHP كود :
#Region "Public Functions"

    
Function Save() As Integer

    End 
Function

    Function 
Update() As Integer

    End 
Function

    Function 
Delete() As Integer

    End 
Function

#End Region 

الآن أنتهينا من التصميم المبدئي لفئة الأشخاص و تبقى فئة الأرقام في المشاركة التالية بإذن الله .


الملفات المرفقة صورة/صور
           
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#3
و الآن ننشئ فئة أرقام الاتصال كالتالي :

[ATTACH=CONFIG]503[/ATTACH]

[ATTACH=CONFIG]504[/ATTACH]

ثم نكتب الكود التالي :

ننشئ تركيبه اسمها نوع الاتصال :

PHP كود :
Public Class ContactNumber

    Enum CallType
        Tel 
1
        Mobil 
2
        Fax 
3
    End Enum 

ثم نعلن عن المتغيرات المحلية :
PHP كود :
#Region "Private Variables"
    
Private _ID As Integer 0
    
Private _PersonID As Integer 0
    
Private _Type As CallType CallType.Mobil
    
Private _Number As String ""
#End Region 
ثم الخصائص
PHP كود :
#Region "Properties"
    
Property ID() As Integer
        Get
            
Return _ID
        End Get
        Set
(ByVal value As Integer)
            
_ID value
        End Set
    End Property
    Property PersonID
() As Integer
        Get
            
Return _PersonID
        End Get
        Set
(ByVal value As Integer)
            
_PersonID value
        End Set
    End Property
    Property Type
() As CallType
        Get
            
Return _Type
        End Get
        Set
(ByVal value As CallType)
            
_Type value
        End Set
    End Property
    Property Number
() As String
        Get
            
Return _Number
        End Get
        Set
(ByVal value As String)
            
_Number value
        End Set
    End Property
#End Region 
فالإجراء المشيد للفئة :

PHP كود :
#Region "Public Functions"

    
Function Save() As Integer

    End 
Function

    Function 
Update() As Integer

    End 
Function

    Function 
Delete() As Integer

    End 
Function

#End Region

End Class 

بهذا نكون قد انتهينا من كتابة الكائنات .


الملفات المرفقة صورة/صور
       
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#4
من نفس مشروعنا الحالي نقوم بعمل بناء Build للحل كما في الصورة :

[ATTACH=CONFIG]505[/ATTACH]


و الآن و بعد أن انتهينا من إنشاء الكائنات نجرب استخدام تلك الكائنات في مشروع جديد

بناء طبقة العرض


ننشئ حل جديد سواءً ويب أو ويندوز (وهذا من مميزات N-Tier )

[ATTACH=CONFIG]506[/ATTACH]

و نضيف له المرجع Reference كالتالي :

[ATTACH=CONFIG]507[/ATTACH]

النتيجة بعد وضع المرجع

[ATTACH=CONFIG]509[/ATTACH]

نضع على النافذة زر ، لنضع تحته الكود :

[ATTACH=CONFIG]510[/ATTACH]

الكود المراد وضعه هو :

PHP كود :
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgsHandles Button1.Click

        Dim oPerson 
As New PhoneBook.Person

        oPerson
.Age 10
        oPerson
.Area "Qassim"
        
oPerson.ID 1
        oPerson
.Job "Programmer"
        
oPerson.Name "Abdullah"
        
oPerson.Save()

    
End Sub 

ثم نحفظ المشروع الجديد كالتالي :

[ATTACH=CONFIG]511[/ATTACH]



الآن ما قمنا به هو إنشاء طبقة العرض تتعامل مع الكائنات ولا علاقة لها بنوعية البيانات أو طريقة حفظها سواءً Datatbase أو ini file أو XML .




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



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


الملفات المرفقة صورة/صور
                       
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#5
السلام عليكم ورحمة الله وبركاته


طبقة البيانات هي الطبقة المعنية بحفظ البيانات (إن كان التطبيق يحتاج لحفظ البيانات) .


و بما أننا في تطبقنا الحالي نحتاج لحفظ أسماء الأشخاص و أرقام هواتفهم فنحن بحاجة لاستخدام طبقة البيانات .

سنعتمد في تطبيقنا الحالي على قواعد البيانات SQL Server 2000 .


و سنجزء العمل في هذه الطبقة إلى جزئين :

1- الجداول Tables .
وهي المكان الذي سيحتفظ في البيانات .

2- الإجراءات المخزنة Stored Procedure .
وهي الكائنات التي ستقوم بتنفيذ العمليات داخل طبقة البيانات ، من حفظ أو حذف أو تعديل أو عرض ( إعتماداً على الجداول ) .



1- الجداول Tables :

حسب تصميم الكائنات المذكور في الأعلى فإننا بحاجة لجدولين هما :
أ - جدول الأشخاص Person .
ب- جدول أرقام الإتصال Contact Number .

أ - جدول الأشخاص Person Table :

سيكون جدول الأشخاص هو مكان حفظ خصائص الكائن Person .
لقد ذكرنا سابقاً بأن خصائص الكائن Person هي :

1. الاسم
2. العمر
3. مكان الإقامة
4. العمل

إذن ، نحن بحاجة لجدول فيه الحقول التالية :
1- حقل الاسم Name و نوعه nVarChar لأن خاصية الاسم عبارة عن سلسلة نصية String (انظر للأعلى إن نسيت هذا) و حجم الحقل هو 255 .

2- حقل العمر Age ونوعه int لأن خاصية العمر هي رقم عددي صحيح Integer .

3- حقل المدينة (مكان الإقامة) City و نوعه Nvarchar و حجمه هو 255 .

4- حقل العمل Job و نوعه nVarchar و حجمه 255 .

س - لماذا تم اختيار نوع البيانات nVarchar ؟
ج - لأنه يدعم الحروف العربية .




ب - جدول أرقام الاتصال Contact Number Table :

سيكون جدول أرقام الاتصال هو مكان حفظ خصائص الكائن Contact Number .
لقد ذكرنا سابقاً بأن خصائص الكائن Contact Number هي :

1. النوع : خلوي ، سكني ، تجاري ، بيجر
2. رقم : نضع فيه الرقم .

إذن ، نحن بحاجة لجدول فيه الحقول التالية :
1- حقل Type نوع البيانات Int و ذلك أن خاصية الكائن هي من نوع تركيبة Enum وهذا النوع من الكائنات يحفظ البيانات كـ أرقام Integer .

2- حقل رقم Number نوع البيانات VarChar و حجمه 255 .


سنكمل في المشاركة التالية بإذن الله بناء الجداول و الإجراءات المخزنة .
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#6
نتابع بناء الجداول كما هو موضح بالصور :

ننشئ قاعدة البيانات و نسميها PhoneBook :

[ATTACH=CONFIG]525[/ATTACH]

[ATTACH=CONFIG]526[/ATTACH]


ثم ننشئ جدول الأشخاص و نسميه Person :

[ATTACH=CONFIG]527[/ATTACH]

[ATTACH=CONFIG]528[/ATTACH]

[ATTACH=CONFIG]529[/ATTACH]

[ATTACH=CONFIG]530[/ATTACH]

[ATTACH=CONFIG]531[/ATTACH]

ثم جدول الأرقام :

[ATTACH=CONFIG]532[/ATTACH]

و نسميه ContactNumber :

[ATTACH=CONFIG]533[/ATTACH]

يمكنك تنفيذ هذا الكود مباشرة داخل SQL Query Analyzer (طبعاً بعدما تنشئ قاعدة البيانات ) :

PHP كود :
/****** Object:  Table [dbo].[ContactNumber]    Script Date: 14/03/2008 04:32:10 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[ContactNumber]') and OBJECTPROPERTY(idN'IsUserTable') = 1)
drop table [dbo].[ContactNumber]
GO

/****** Object:  Table [dbo].[Person]    Script Date: 14/03/2008 04:32:10 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[Person]') and OBJECTPROPERTY(idN'IsUserTable') = 1)
drop table [dbo].[Person]
GO

/****** Object:  Table [dbo].[ContactNumber]    Script Date: 14/03/2008 04:32:10 م ******/
CREATE TABLE [dbo].[ContactNumber] (
    [
ID] [bigintIDENTITY (11NOT NULL ,
    [
Type] [intNULL ,
    [
Number] [varbinary] (255NULL ,
    [
PersonID] [bigintNULL 
ON [PRIMARY]
GO

/****** Object:  Table [dbo].[Person]    Script Date: 14/03/2008 04:32:11 م ******/
CREATE TABLE [dbo].[Person] (
    [
ID] [intIDENTITY (11NOT NULL ,
    [
Name] [nvarchar] (255COLLATE Arabic_CI_AS NULL ,
    [
Age] [intNULL ,
    [
Area] [nvarchar] (255COLLATE Arabic_CI_AS NULL ,
    [
Job] [nvarchar] (255COLLATE Arabic_CI_AS NULL 
ON [PRIMARY]
GO

ALTER TABLE 
[dbo].[ContactNumberWITH NOCHECK ADD 
    CONSTRAINT 
[PK_ContactNumberPRIMARY KEY  CLUSTERED 
    
(
        [
ID]
    )  
ON [PRIMARY
GO

ALTER TABLE 
[dbo].[PersonWITH NOCHECK ADD 
    CONSTRAINT 
[PK_PersonPRIMARY KEY  CLUSTERED 
    
(
        [
ID]
    )  
ON [PRIMARY
GO 

---------------------------------------------------


الملفات المرفقة صورة/صور
                                   
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#7
السلام عليك ورحمة الله وبركاته


بعدما بنينا الجداول في قاعدة البيانات نأتي للجزء الثاني من طبقة البيانات وهو الإجراءات المخزنة .


س- ما هو الإجراء المخزن ؟

ج- http://www.arabteam2000-forum.com/in...howtopic=84176




في الـ N-Tier الإجراء المخزن Stored Procedure سيكون المقابل لسلوك الفئة الذي يتطلب اتصال مع جدول قاعدة البيانات .


بعبارة أخرى ،،،

نحن نقول في فئة Person هناك وظيفة (دالة) اسمها Delete تقوم بحذف بيانات الكائن الحالي في الجدول .

هذه الدالة Delete تحتاج لإجراء مخزن داخل قاعدة البيانات .

لهذا ننشئ إجراء مخزن أسمه sp_Delete_Person

و نضع بداخله الكود التالي :

PHP كود :
CREATE PROC sp_Delete_Person
@Id as bigint
as
Delete From  Person where ID=@Id
GO 


هذا الإجراء المخزن يستقبل بارميتر اسمه @Id من نوع Bigint

سيتم استخدام هذا البارميتر في تنفيذ الاستعلام :
PHP كود :
Delete From  Person where ID=@Id 


و كما قلنا سابقاً ، كل سلوك للفئة له علاقة بقاعدة البيانات لابد أن يكون له إجراء مخزن .

و على هذا فنحن بحاجة لـ 4 إجراءات مخزنة على الأقل تقابل كل فئة بنيناها في طبقة الأعمال ، و ستكون هذه الإجراءات كالتالي :

sp_Add_Person
sp_Delete_Person
sp_Update_Person
sp_Select_Person


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

PHP كود :
/****** Object:  Stored Procedure dbo.sp_Add_Person    Script Date: 14/03/2008 05:50:23 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Add_Person]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Add_Person]
GO

/****** Object:  Stored Procedure dbo.sp_Delete_Person    Script Date: 14/03/2008 05:50:23 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Delete_Person]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Delete_Person]
GO

/****** Object:  Stored Procedure dbo.sp_Select_Person    Script Date: 14/03/2008 05:50:23 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Select_Person]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Select_Person]
GO

/****** Object:  Stored Procedure dbo.sp_Update_Person    Script Date: 14/03/2008 05:50:23 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Update_Person]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Update_Person]
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Add_Person    Script Date: 14/03/2008 05:50:24 م ******/
CREATE Proc sp_Add_Person

@ID bigint OUTPUT,
@
Name nvarchar(255),
@
Age int,
@
Area nvarchar(255),
@
Job nvarchar(255)

as
insert into Person([Name],Age,Area,Job)
values
(
@
Name ,
@
Age ,
@
Area ,
@
Job 
);
Select @ID=Scope_Identity();
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Delete_Person    Script Date: 14/03/2008 05:50:24 م ******/
CREATE PROC sp_Delete_Person
@Id as bigint
as
Delete From  Person where ID=@Id
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Select_Person    Script Date: 14/03/2008 05:50:24 م ******/
CREATE PROC sp_Select_Person
@Id as bigint
as
Select *  From  Person where ID=@Id
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Update_Person    Script Date: 14/03/2008 05:50:24 م ******/
CREATE Proc sp_Update_Person
@ID bigint ,
@
Name nvarchar(255),
@
Age int,
@
Area nvarchar(255),
@
Job nvarchar(255)
as
Update Person set
[Name] =@Name ,
Age=@Age ,
Area=@Area ,
job=@Job 
where 
[ID]=@ID
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO 


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

و بنفس الطريقة أتمنى أن تقوم بعمل الإجراءات المخزنة للفئة ContactNumber


أتمنى لكم التوفيق ،

و للحديث بقية إن شاء الله ،،،
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#8
السلام عليكم ورحمة الله وبركاته


إنتهى بنا الحديث حول الإجراءات المخزنة في قاعدة البيانات ، لقد تبقى الإجراءات المخزنة الخاصة بجدول ContactNumber ، وهي على النحو التالي :

PHP كود :
/****** Object:  Stored Procedure dbo.sp_Add_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Add_ContactNumber]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Add_ContactNumber]
GO

/****** Object:  Stored Procedure dbo.sp_Delete_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Delete_ContactNumber]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Delete_ContactNumber]
GO

/****** Object:  Stored Procedure dbo.sp_Select_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Select_ContactNumber]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Select_ContactNumber]
GO

/****** Object:  Stored Procedure dbo.sp_Update_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
if exists (select from dbo.sysobjects where id object_id(N'[dbo].[sp_Update_ContactNumber]') and OBJECTPROPERTY(idN'IsProcedure') = 1)
drop procedure [dbo].[sp_Update_ContactNumber]
GO

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Add_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
CREATE Proc sp_Add_ContactNumber

@ID bigint OUTPUT,
@
Type int,
@
Number varchar(255),
@
PersonID bigint
as
insert into ContactNumber(Type,Number,PersonID)
values
(
@
Type ,
@
Number ,
@
PersonID
);
Select @ID=Scope_Identity();
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Delete_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
CREATE PROC sp_Delete_ContactNumber
@Id as bigint
as
Delete From  ContactNumber where ID=@Id
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Select_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
CREATE PROC sp_Select_ContactNumber
@Id as bigint
as
Select *  From  ContactNumber where ID=@Id
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS OFF 
GO

/****** Object:  Stored Procedure dbo.sp_Update_ContactNumber    Script Date: 14/03/2008 10:11:14 م ******/
CREATE Proc sp_Update_ContactNumber
@ID bigint ,
@
Type int,
@
Number varchar(255),
@
PersonID bigint

as
Update ContactNumber set

Type 
=@Type ,
Number =@Number ,
PersonID =@PersonID

where 
[ID]=@ID
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO 



و الآن و بعدما انهينا طبقة البيانات بشقيها (الجداول و الإجراءات المخزنة) نعود لطبقة الأعمال .

و الهدف هو إضافة بعض الدوال التي تتعامل مع الإجراءات المخزنة في طبقة البيانات .


سننشئ 4 دوال محلية Private في كل كائن لاستدعاء الإجراءات المخزنة .

إذن نحن بحاجة لـ

PHP كود :
Private Function _Save as Integer 

و مثلها للحذف

PHP كود :
Private Function _Delete as Integer 


و التعديل


PHP كود :
Private Function _Update as Integer 

و العرض


PHP كود :
Private Function _Select as DataTable 



أتمنى أن تكون قد لاحظت الفرق بين تلك الوظائف ، حسناً الفرق أن جميع تلك الوظائف تعيد قيمة Integer ما عدا Select فهي تعيد DataTable .

أما عن سبب الفرق ؟
فهو أن كل وظيفة من الوظائف التي تعيد Integer الهدف منها معرفة هل تم تنفيذ الاستعلام أم لا .

بينما الدالة Select فنحن نريدها أن تعيد أكثر من ذلك ، فنحن نريدها أن تعديل لنا الصفوف التي تم اختيارها .



و على ما سبق ،،،
سيكون الكود في الوظائف السابقة هو كالتالي :

1- دالة الإضافة و لاحظ استدعاء الإجراء المخزن sp_Add_Person :

PHP كود :
Private Function _Save(ByVal Name As String_
                           ByVal Age 
As Integer_
                           ByVal Area 
As String_
                           ByVal Job 
As String) As Integer
        Dim insCMD 
As New SqlClient.SqlCommand
        
Try

            
With insCMD
                
.Connection Me._Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Add_Person"
                
.Parameters.Add("@Name"SqlDbType.NVarChar255).Value Name
                
.Parameters.Add("@Age"SqlDbType.Int).Value Age
                
.Parameters.Add("@Area"SqlDbType.NVarChar).Value Area
                
.Parameters.Add("@Job"SqlDbType.NVarChar255).Value Job

            End With

            Dim paramID 
As New SqlClient.SqlParameter("@ID"System.Data.SqlDbType.BigInt)
            
paramID.Direction System.Data.ParameterDirection.Output
            insCMD
.Parameters.Add(paramID)

            
Dim con As New SqlClient.SqlConnection(Me.Connection.ConnectionString)
            If 
Me.Connection.State ConnectionState.Open Then Me.Connection.Close()
            
Connection.Open()
            
insCMD.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
CType(insCMD.Parameters("@ID").Value.ToString(), Integer)

    
End Function 


2- دالة التعديل و لاحظ استدعاء الإجراء المخزن sp_Update_Person :

PHP كود :
Private Function _Update(ByVal ID As Integer_
                             ByVal Name 
As String_
                             ByVal Age 
As Integer_
                             ByVal Area 
As String_
                             ByVal Job 
As String) As Integer
        Dim i 
As Integer
        
Try
            
Dim UpdCmd As New SqlClient.SqlCommand
            With UpdCmd
                
.Connection Me.Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Update_Person"
                
.Parameters.Add("@ID"SqlDbType.BigInt).Value ID
                
.Parameters.Add("@Name"SqlDbType.NVarChar255).Value Name
                
.Parameters.Add("@Age"SqlDbType.Int).Value Age
                
.Parameters.Add("@Area"SqlDbType.NVarChar).Value Area
                
.Parameters.Add("@Job"SqlDbType.NVarChar255).Value Job
            End With
            
If Connection.State ConnectionState.Open Then Connection.Close()
            
Connection.Open()
            
UpdCmd.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
i

    End 
Function 

3- دالة الحذف ولاحظ استدعاء الإجراء المخزن sp_Delete_Person :
PHP كود :
Private Function _Delete(ByVal Id As Integer) As Integer

        Dim i 
As Integer
        
Try
            
Dim delCmd As New SqlClient.SqlCommand
            With delCmd
                
.Connection Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Delete_Person"
                
.Parameters.Add("@Id"SqlDbType.BigInt).Value Id
            End With
            
If Connection.State ConnectionState.Open Then Connection.Close()
            
Connection.Open()
            
delCmd.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
i
    End 
Function 


4- دالة العرض ، ولاحظ :
استدعاء الإجراء المخزن sp_Select_Person
إعادة الدالة البيانات على هيئة DataTable


PHP كود :
Private Function _Select(ByVal ID As Integer) As DataTable

        Dim dsv 
As New DataTable
        
Try
            
Dim SelCmd As New SqlClient.SqlCommand
            SelCmd
.CommandType CommandType.StoredProcedure
            SelCmd
.CommandText "sp_Select_Person"
            
SelCmd.Parameters.Add("@Id"SqlDbType.BigInt).Value ID

            SelCmd
.Connection Connection
            Dim dAdapter 
As New SqlClient.SqlDataAdapter(SelCmd)

            
dAdapter.Fill(dsv)

        Catch 
ex As Exception

        End 
Try

        Return 
dsv
    End 
Function 



سنقوم بنفس العمل مع الكائن ContactNumber .

أتمنى أن تجرب بنفسك أو أن تنتظر إلى مشاركة قادمة بإذن الله .


و السلام عليكم ورحمة الله وبركاته
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#9
السلام عليكم ورحمة الله وبركاته

نستطيع أن نقسم طبقة الأعمال كما قسمنا طبقة البيانات إلى قسمين .


القسم الأول : الدوال العامة . و التي يتعامل معها المستخدم (المبرمج) و هي الطبقة العلوية للكائن .
القسم الثاني : الداول المحلية . و التي تقع بين الدوال العامة و الإجراءات المخزنة ، وهي الطبقة السفلية للكائن .



في المشاركة السابقة بدأنا في الدوال المحلية للفئة Person و الآن نكمل الدوال المحلية و نسرد دوال الفئة ContactNumber .

بدون شرح هي كالتالي :

PHP كود :
#Region "Private Functions"
    
Private Function _Save(ByVal PersonID As Integer_
                           ByVal Type 
As CallType_
                           ByVal Number 
As String) As Integer
        Dim insCMD 
As New SqlClient.SqlCommand
        
Try

            
With insCMD
                
.Connection Me._Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Add_ContactNumber"
                
.Parameters.Add("@PersonID"SqlDbType.Int).Value PersonID
                
.Parameters.Add("@Type"SqlDbType.Int).Value Type
                
.Parameters.Add("@Number"SqlDbType.NVarChar255).Value Number

            End With

            Dim paramID 
As New SqlClient.SqlParameter("@ID"System.Data.SqlDbType.BigInt)
            
paramID.Direction System.Data.ParameterDirection.Output
            insCMD
.Parameters.Add(paramID)

            
Dim con As New SqlClient.SqlConnection(Me.Connection.ConnectionString)
            If 
Me.Connection.State ConnectionState.Open Then Me.Connection.Close()
            
Connection.Open()
            
insCMD.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
CType(insCMD.Parameters("@ID").Value.ToString(), Integer)

    
End Function
    Private Function 
_Update(ByVal ID As Integer_
                             ByVal PersonID 
As Integer_
                             ByVal Type 
As CallType_
                             ByVal Number 
As String) As Integer
        Dim i 
As Integer
        
Try
            
Dim UpdCmd As New SqlClient.SqlCommand
            With UpdCmd
                
.Connection Me.Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Update_ContactNumber"
                
.Parameters.Add("@ID"SqlDbType.BigInt).Value ID
                
.Parameters.Add("@PersonID"SqlDbType.Int).Value PersonID
                
.Parameters.Add("@Type"SqlDbType.Int).Value Type
                
.Parameters.Add("@Number"SqlDbType.NVarChar255).Value Number
            End With
            
If Connection.State ConnectionState.Open Then Connection.Close()
            
Connection.Open()
            
UpdCmd.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
i

    End 
Function
    Private Function 
_Delete(ByVal Id As Integer) As Integer

        Dim i 
As Integer
        
Try
            
Dim delCmd As New SqlClient.SqlCommand
            With delCmd
                
.Connection Connection
                
.CommandType CommandType.StoredProcedure
                
.CommandText "sp_Delete_ContactNumber"
                
.Parameters.Add("@Id"SqlDbType.BigInt).Value Id
            End With
            
If Connection.State ConnectionState.Open Then Connection.Close()
            
Connection.Open()
            
delCmd.ExecuteNonQuery()
            
Connection.Close()

        Catch 
ex As Exception

        End 
Try

        Return 
i
    End 
Function
    Private Function 
_Select(ByVal ID As Integer) As DataTable

        Dim dsv 
As New DataTable
        
Try
            
Dim SelCmd As New SqlClient.SqlCommand
            SelCmd
.CommandType CommandType.StoredProcedure
            SelCmd
.CommandText "sp_Select_ContactNumber"
            
SelCmd.Parameters.Add("@Id"SqlDbType.BigInt).Value ID

            SelCmd
.Connection Connection
            Dim dAdapter 
As New SqlClient.SqlDataAdapter(SelCmd)

            
dAdapter.Fill(dsv)

        Catch 
ex As Exception

        End 
Try

        Return 
dsv
    End 
Function

#End Region 


بعد ذلك نبدأ في الدوال العامة .

و هي الداول التي سيستدعيها المستخدم مثل دالة Save و الخاصة بالحفظ و Delete الخاصة بالحذف .


ما ستقوم به هذه الدوال هو :
استدعاء الدوال المحلية و تمرير خصائص الكائن لها كبارميترات .


و عليه ، ستكون دالة الحفظ في الكائن Person كالتالي :


PHP كود :
Function Save() As Integer

        
Return Me._Save(Me._PersonIDMe._TypeMe._Number)

    
End Function 


ستعيد الدالة عدد الأسطر المتأثرة ، 1 في حال النجاح و صفر في حال الفشل .



أما دالة التعديل فهي كالتالي :


PHP كود :
Function Update() As Integer

        
Return Me._Update(Me._IDMe._PersonIDMe._TypeMe._Number)

    
End Function 
النتيجة ستكون نفس الدالة السابقة .



أما الحذف فهي كالتالي :

PHP كود :
Function Delete() As Integer

        
Return Me._Delete(Me._ID)

    
End Function 

القيمة العائدة نفس الكلام في الدالتين السابقتين .



تبقى دالة العرض Select ؟

هذا محتاجة شوي تركيز عشان كذا نأجلها في مشاركة مستقلة .


أرفق لكم الحل حسب أخر تحديث .
كما أرفق لكم ملف كامل لبناء الجداول و الإجراءات المخزنة في قاعدة البيانات .
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:
#10
الحمد لله جت المشاركة المستقلة بعد طول غياب


كما أوضحنا سابقاً هناك 3 دوال عامة Save , Update , Delete
و يقابلها 3 دوال خاصة _Save , _Update , _Delete

و انتهينا من بناء دوال الكائن التي تقوم بالإضافة و الحذف و التعديل .

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



لهذا نحن بحاجة للدالة الخاصة _Select و التي تعود بكائن من نوع DataTable .

هذه الدالة الخاصة أقصد _Select تأخذ بارميتر واحد وحو رقم الكائن ، و الذي هو رقم السجل داخل الجدول المقابل لهذا الكلاس (الفئة) .


كما ذكرنا سابقاً فإن الدالة سيكون شكلها كالتالي :

PHP كود :
Private Function _Select(ByVal ID As Integer) As DataTable

        Dim dsv 
As New DataTable
        
Try
            
Dim SelCmd As New SqlClient.SqlCommand
            SelCmd
.CommandType CommandType.StoredProcedure
            SelCmd
.CommandText "sp_Select_ContactNumber"
            
SelCmd.Parameters.Add("@Id"SqlDbType.BigInt).Value ID

            SelCmd
.Connection Connection
            Dim dAdapter 
As New SqlClient.SqlDataAdapter(SelCmd)

            
dAdapter.Fill(dsv)

        Catch 
ex As Exception

        End 
Try

        Return 
dsv
    End 
Function 


و الآن كيف سنحمل البيانات من الجدول إلى الكلاس ؟

و الجواب هو عند الخاصية ID

للتذكير كان الكود الموجود تحت الخاصية ID هو :

PHP كود :
Property ID() As Integer
        Get
            
Return _ID
        End Get
        Set
(ByVal value As Integer)
            
_ID value
        End Set
    End Property 



و الآن نحن بحاجة لإضافة بعض الأسطر التي ستفحص القيمة المدخلة للخاصية ثم تستدعي الدالة الخاصة _Select لأجل إحضار البيانات ثم تعبئة الخصائص بالقيمة العائدة من الدالة .

سيكون الكود المكتوب عند الخاصية ID كالتالي :


PHP كود :
Property ID() As Integer
        Get
            
Return _ID
        End Get
        Set
(ByVal value As Integer)

            
'   نعمل استعلام من قاعدة البيانات و نعبئ الكلاس بالقيم
            Dim dTable As DataTable = Me._Select(value)

            ' 
إذا كان عدد السجلات أكثر من صفر بعبارة أخرى إذا كان هناك سجلات
            
If dTable.Rows.Count 0 Then
                
' إقرأ القيمة من الجدول و ضعها في الخاصية
                Me._ID = Integer.Parse(dTable.Rows(0).Item("ID").ToString)
                Me._Type = Integer.Parse(dTable.Rows(0).Item("Type").ToString)
                Me._Number = dTable.Rows(0).Item("Number").ToString
                Me._PersonID = Integer.Parse(dTable.Rows(0).Item("PersonID").ToString)
            End If


        End Set
    End Property 


و الآن ....

انتهينا من طريقة جلب البيانات و عرضها على الكلاس (كخصائص للكلاس) .



و نفس الكلام على الكلاس Person ، نضيف تحت الخاصية ID الكود التالي :

Property ID() As Integer
Get
Return _ID
End Get
Set(ByVal value As Integer)

' نعمل استعلام من قاعدة البيانات و نعبئ الكلاس بالقيم
Dim dTable As DataTable = Me._Select(value)

' إذا كان عدد السجلات أكثر من صفر بعبارة أخرى إذا كان هناك سجلات
If dTable.Rows.Count > 0 Then
' إقرأ القيمة من الجدول و ضعها في الخاصية
Me._ID = Integer.Parse(dTable.Rows(0).Item("ID").ToString)
Me._Name = dTable.Rows(0).Item("Name").ToString
Me._Age = Integer.Parse(dTable.Rows(0).Item("Age").ToString)
Me._Area = dTable.Rows(0).Item("Area").ToString
Me._Job = dTable.Rows(0).Item("Job").ToString
End If


End Set
End Property

و بهذا نكون أنهينا طبقة الأعمال و بإمكانك استخدام الكلاسين في مشاريعك القادمة

الحمد لله الذي بنعمته تتم الصالحات ،


الملفات المرفقة
.rar   2008-07-31-PhoneBook.rar (الحجم : 37.32 ك ب / التحميلات : 65)
http://www.elfouadsoft.com
mohamed_tegara@yahoo.com
الرد }}}
تم الشكر بواسطة:



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم