ناتي الان للمفيد و الشغل الجامد
الكلاس الثاني في مشروعنا هو كلاس التعامل مع قاعدة البيانات (الحذف و التعديل و الاضافة)
بس؟؟؟؟
بس و الباقي عليك انت؟؟
وجهة نظري تقول اذا كنت قد حصلت على اتصال مع السرفر و حددت القاعدة و الجدول الذي اريده و لدي ايضا كل الحقول التي اريدها
لماذا لا يكون لدي جمل استعلام ديناميكية تقوم لوحدها بتركيب نفسها اعتمادا على مدخلات بسيطة مني
فقط انا امرر اسماء الحقول و هي تقوم بعمل جمل (SELECT,INSERT,UPDATE,DELETE) لوحدها دون ان اقوم انا بكتابتها
تخيل معي لو كان لديك جدول فيه 50 حقل هل ساقوم انا بكتابتها و اعيد تكرار الكتابة و ووووو.....؟ عمل ممل و سقيم
اذا ما الفائدة من الكلاس اللي عملناه..؟ سؤال وجيه يحتاج لاجابة
لندخل في المفيد
انشأ كلاس جديد و اضفه الى المشروع و سميه DbConect
داخل الكلاس استورد المراجع التالية و قم بتوريث الكلاس السابق الى الكلاس الجديد للاستفادة من الكائنات التي عملناها سابقا
ان فكرةعمل كلاس خاص بكل جدول و بكل الحقول الخاصة فيه هي فكرة لا تلبي حاجتنا لان الجداول متغيرة و كذلك الحقول و انا اريد كلاس ديناميكي
اذا ساحاول الاستفادة من الكلاس السابق لاقصى درجة ممكنة
الفكرة التي لدي هي الاستفادة من الجداول و الحقول التي خزناها سابقا و جلبها الى مصفوفات خاصة و من ثم التعامل معها عبر المصفوفات
الان مجموعة من المتغيرات في بداية الكلاس مع الشرح داخلها
شرح بسيط عن المصفوفة رباعية الابعاد (جدول باربع اعمده ليسهل الفهم)
البعد الثالث في هذه المصفوفة هو لتخزين بارميتر خاص مرافق للحقل
اذ قررت ان اتعامل مع الكائن SQL COMMAND للتخاطب مع قاعدة البيانات و بالتالي انا مضطر لارسال بارميتر لكل حقل اريد تحديثه هذا يقودنا الى مجموعه من البارمترات كذلك متغيرة على حسب عدد الحقول بالمختصر المفيد انا اجهل عددها و اسمائها لذا ستكون البارمترات على حسب عدد الحقول التي ناتي بها مع استثناء حقل المفتاح الرئيسي اثناء عملية الاضافة
عملية انشاء البارمترات ستتم وفق اسم الحقل في مصفوفة الحقول على فرض انا لدي حقل اسمه Name البارميتر المناسب سيكون @Name
و هكذا ....
في البداية بعد تاسيس الاتصال مع القاعدة ساكون بحاجه الى جدول للتعامل معه , لذا سأنشئ خاصية للتعامل مع الجدول باتجاهين
استطيع من خلالها اسناد اسم للجدول و كذلك معرفة اسم الجدول الحالي
طبعا في الكود السابق ساستفيد من مصفوفة الجداول التي انشأناها سابقا للتاكد من وجود اسم الجدول ضمن المصفوفة بعد ان يكون المستخدم قد ادخله و من ثم العودة باسم الجدول
بعد الحصول على الجدول يتبقى الحصول على الحقول بداخله بخاصية للقراءة فقط اذ ان اسماء الحقول ستاتي جاهزة كما هي
بعد ذلك انا امام اجراء كبير لكنه سهل في مجمله و الغاية منه هو ملئ المصفوفات التي عرفناها فوق بالمعلومات عن كل الحقول
انا شرحت الكود ضمن التعليقات داخله
بعد ان تم ملئ المصفوفات بالبيانات اللازمة جاء دور العمل مع جمل الاستعلام الديناميكية و الاستفادة من كل المعلومات السابقة لاستخلاص جملة تحديد مناسبة على ذوق المبرمج
انا فضلت العمل بطريقتين هنا
اذا ود المبرمج ان يحدد كل الحقول فعليه ان يختار المعامل *
و اذا ود اختيار مجموع من الحقول فقط فعليه ادخال اسماء الحقول فقط ضمن مصفوفة بسيط (مصفوفة من ثاني
)
نسيت ان اشير الى جزئية هامة في الكود السابق و هي نوع بيانات الحقول القادمة من SQL SERVER يتم تحويلها الى انواع تتوافق مع اطار العمل
انا قمت بتحويل بعض الانواع فقط لذا يمكنك ان تقوم بتوسيع عملية التحويل حسب رغبتك
يتبع.............
الكلاس الثاني في مشروعنا هو كلاس التعامل مع قاعدة البيانات (الحذف و التعديل و الاضافة)
بس؟؟؟؟
بس و الباقي عليك انت؟؟
وجهة نظري تقول اذا كنت قد حصلت على اتصال مع السرفر و حددت القاعدة و الجدول الذي اريده و لدي ايضا كل الحقول التي اريدها
لماذا لا يكون لدي جمل استعلام ديناميكية تقوم لوحدها بتركيب نفسها اعتمادا على مدخلات بسيطة مني
فقط انا امرر اسماء الحقول و هي تقوم بعمل جمل (SELECT,INSERT,UPDATE,DELETE) لوحدها دون ان اقوم انا بكتابتها
تخيل معي لو كان لديك جدول فيه 50 حقل هل ساقوم انا بكتابتها و اعيد تكرار الكتابة و ووووو.....؟ عمل ممل و سقيم
اذا ما الفائدة من الكلاس اللي عملناه..؟ سؤال وجيه يحتاج لاجابة
لندخل في المفيد
انشأ كلاس جديد و اضفه الى المشروع و سميه DbConect
داخل الكلاس استورد المراجع التالية و قم بتوريث الكلاس السابق الى الكلاس الجديد للاستفادة من الكائنات التي عملناها سابقا
PHP كود :
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Sdk.Sfc
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class DbConect
Inherits ServSite
ان فكرةعمل كلاس خاص بكل جدول و بكل الحقول الخاصة فيه هي فكرة لا تلبي حاجتنا لان الجداول متغيرة و كذلك الحقول و انا اريد كلاس ديناميكي
اذا ساحاول الاستفادة من الكلاس السابق لاقصى درجة ممكنة
الفكرة التي لدي هي الاستفادة من الجداول و الحقول التي خزناها سابقا و جلبها الى مصفوفات خاصة و من ثم التعامل معها عبر المصفوفات
الان مجموعة من المتغيرات في بداية الكلاس مع الشرح داخلها
PHP كود :
Private WithEvents _adapter As SqlClient.SqlDataAdapter
''' <summary>
''' مصفوفة من بعدين
''' البعد الاول يخزن اسم الحقل
''' البعد الثاني يخزن نوع البيانات
''' </summary>
''' <remarks></remarks>
Dim Column(2, 0)
''' <summary>
''' مصفوفة ببعد واحد لتخزين اسماء حقول الجدول
''' </summary>
''' <remarks></remarks>
Dim AllColumn() As String
''' <summary>
'''متغير جدول بيانات نخزن فيه حقول جدول قاعدة
''' السيكوال الذي مررناه للتعامل معه
''' </summary>
''' <remarks></remarks>
Protected Dt As DataTable
''' <summary>
''' مصفوفة من النوع حقل بيانات
''' لتخزين المفتاح الرئيسي في الكائن جدول البيانات
''' </summary>
''' <remarks></remarks>
Dim kyes(0) As DataColumn
Dim allParameters() As SqlParameter
''' <summary>
''' مصفوفة رباعية الابعاد
''' البعد الاول نخزن فيه اسم الحقل
''' البعد الثاني لتخزين نوع بيانات الحقل
''' البعد الثالث لتخزين اسم بارميتر مرافق للحقل
''' البعد الرابع نخزن فين نص يشير الى حقل المفتاح الرئيسي
''' </summary>
''' <remarks></remarks>
Dim InsUpSel(4, 0) 'As String
''' <summary>
''' متغير نصي نستخدمه للاحتفظ باسم الجدول الذي نريد التعامل معه
''' </summary>
''' <remarks></remarks>
Protected _TableName As String
شرح بسيط عن المصفوفة رباعية الابعاد (جدول باربع اعمده ليسهل الفهم)
البعد الثالث في هذه المصفوفة هو لتخزين بارميتر خاص مرافق للحقل
اذ قررت ان اتعامل مع الكائن SQL COMMAND للتخاطب مع قاعدة البيانات و بالتالي انا مضطر لارسال بارميتر لكل حقل اريد تحديثه هذا يقودنا الى مجموعه من البارمترات كذلك متغيرة على حسب عدد الحقول بالمختصر المفيد انا اجهل عددها و اسمائها لذا ستكون البارمترات على حسب عدد الحقول التي ناتي بها مع استثناء حقل المفتاح الرئيسي اثناء عملية الاضافة
عملية انشاء البارمترات ستتم وفق اسم الحقل في مصفوفة الحقول على فرض انا لدي حقل اسمه Name البارميتر المناسب سيكون @Name
و هكذا ....
في البداية بعد تاسيس الاتصال مع القاعدة ساكون بحاجه الى جدول للتعامل معه , لذا سأنشئ خاصية للتعامل مع الجدول باتجاهين
استطيع من خلالها اسناد اسم للجدول و كذلك معرفة اسم الجدول الحالي
PHP كود :
''' <summary>
''' خاصية اسناد اسم للجدول للتعامل معه
''' او الحصول على اسم الجدول
''' </summary>
''' <value>حدد اسم الجدول كنص</value>
''' <returns>نص يمثل اسم الجدول</returns>
''' <remarks>
''' يتوجب ان يكون هتاك اتصال مع قاعدة البيانت
''' كما يتوجب تحديد اسم الجدول بشكل صحيح
''' </remarks>
Property TableName() As String
Set(ByVal value As String)
If _SqlConnectionString Is Nothing Or _SqlConnectionString = "" Then
MsgBox("تاكد من تاسيس نص الاتصال", , "From TableName")
Exit Property
End If
'------------------------------------------
For i As Integer = 0 To TablesSrvDbs.Length - 1
If (value = TablesSrvDbs(i)) Then
_TableName = value
LoadTxtFiled()
ElseIf i >= TablesSrvDbs.Length And (value <> TablesSrvDbs(i)) Then
_TableName = ""
End If
Next
'---------------------------------------
If _TableName = "" Then
MsgBox("حدد اسم الجدول بشكل صحيح", , "From TableName")
Exit Property
End If
End Set
Get
Return _TableName
End Get
End Property
طبعا في الكود السابق ساستفيد من مصفوفة الجداول التي انشأناها سابقا للتاكد من وجود اسم الجدول ضمن المصفوفة بعد ان يكون المستخدم قد ادخله و من ثم العودة باسم الجدول
بعد الحصول على الجدول يتبقى الحصول على الحقول بداخله بخاصية للقراءة فقط اذ ان اسماء الحقول ستاتي جاهزة كما هي
PHP كود :
ReadOnly Property GetAllFields() As String
Get
If _TableName = "" Then
Return MsgBox("حدد اسم الجدول اولا", , "From GetAllFields")
Exit Property
End If
Dim op As String = ""
For i = 0 To AllColumn.Length - 1
op += AllColumn(i) & vbCrLf
Next
Return op
End Get
End Property
بعد ذلك انا امام اجراء كبير لكنه سهل في مجمله و الغاية منه هو ملئ المصفوفات التي عرفناها فوق بالمعلومات عن كل الحقول
انا شرحت الكود ضمن التعليقات داخله
PHP كود :
''' <summary>
''' اجراء تخزين اسماء الاعمدة و نوعها في مصفوفة
'''هذا الاجراء يقوم بالمرور على كل اعمدة الجدول المحدد
'''AllCoulmn يقوم بتخزين اسماء الاعمدة في مصفوفة نصية
'''Coulmn(,) يقوم بتخزين اسماء الاعمدة و نوعها في مصفوفة نصية ثنائية البعد
''' Dt As DataTable يقوم بتخزين الاعمدة في جدول من النوع
''' DT كما و يقوم باضافة المفتاح الرئيسي الى الجدول
''' InsUpSel(4,0) و يخزن ايضا اسماء الاعمدة و بارميتر لكل عمود و المفتاح الرئيسي ونوع البيانات في
''' </summary>
Protected Sub LoadTxtFiled()
'================================
If _TableName = "" Then
Return
End If
'=================================
Dim Tabl_name As String = _TableName
Dim tb As Table = Srv.Databases(SqlDbName).Tables(Tabl_name)
Dim cs As Integer = 0
'
Dt = New DataTable()
Dt.Columns.Clear()
Array.Clear(kyes, 0, kyes.Length)
'================================
For Each dc As Column In tb.Columns
'
Dim DTc As New DataColumn
DTc.ColumnName = dc.Name
DTc.AllowDBNull = dc.Nullable
'
ReDim Preserve InsUpSel(4, cs)
ReDim Preserve AllColumn(cs)
AllColumn.SetValue(dc.Name, cs)
InsUpSel.SetValue(dc.Name, 0, cs)
'
ReDim Preserve Column(2, cs)
Column.SetValue(dc.Name, 0, cs)
Select Case (dc.DataType.SqlDataType)
Case Is = SqlDataType.NVarChar
Column.SetValue(SqlDbType.NVarChar, 1, cs)
InsUpSel.SetValue(SqlDbType.NVarChar, 1, cs)
DTc.DataType = System.Type.GetType("System.String")
Case Is = SqlDataType.VarChar
Column.SetValue(SqlDbType.VarChar, 1, cs)
InsUpSel.SetValue(SqlDbType.VarChar, 1, cs)
DTc.DataType = System.Type.GetType("System.String")
Case Is = SqlDataType.NChar
Column.SetValue(SqlDbType.NChar, 1, cs)
InsUpSel.SetValue(SqlDbType.NChar, 1, cs)
DTc.DataType = System.Type.GetType("System.String")
Case Is = SqlDataType.Int
Column.SetValue(SqlDbType.Int, 1, cs)
InsUpSel.SetValue(SqlDbType.Int, 1, cs)
DTc.DataType = System.Type.GetType("System.Int32")
Case Is = SqlDataType.Date
Column.SetValue(SqlDbType.Date, 1, cs)
InsUpSel.SetValue(SqlDbType.Date, 1, cs)
DTc.DataType = System.Type.GetType("System.DateTime")
Case Is = SqlDataType.DateTime
Column.SetValue(SqlDbType.DateTime, 1, cs)
InsUpSel.SetValue(SqlDbType.DateTime, 1, cs)
DTc.DataType = System.Type.GetType("System.DateTime")
Case Is = SqlDataType.Float
Column.SetValue(SqlDbType.Float, 1, cs)
InsUpSel.SetValue(SqlDbType.Float, 1, cs)
DTc.DataType = System.Type.GetType("System.Double")
Case Is = SqlDataType.Image
Column.SetValue(SqlDbType.Image, 1, cs)
InsUpSel.SetValue(SqlDbType.Image, 1, cs)
DTc.DataType = System.Type.GetType("System.Byte")
Case Is = SqlDataType.Decimal
Column.SetValue(SqlDbType.Decimal, 1, cs)
InsUpSel.SetValue(SqlDbType.Decimal, 1, cs)
DTc.DataType = System.Type.GetType("System.Decimal")
End Select
InsUpSel.SetValue("@" & dc.Name, 2, cs)
If dc.InPrimaryKey Then
Column.SetValue("prim", 2, cs)
InsUpSel.SetValue("prim", 3, cs)
'
DTc.AutoIncrement = True
DTc.AutoIncrementSeed = -1
DTc.AutoIncrementStep = -1
DTc.AllowDBNull = False
DTc.ReadOnly = True
DTc.Unique = True
ReDim kyes(cs)
kyes(cs) = DTc
Dt.Columns.Add(DTc)
End If
cs += 1
Next
If kyes.Length > 0 Then
Dt.PrimaryKey = kyes
End If
End Sub
بعد ان تم ملئ المصفوفات بالبيانات اللازمة جاء دور العمل مع جمل الاستعلام الديناميكية و الاستفادة من كل المعلومات السابقة لاستخلاص جملة تحديد مناسبة على ذوق المبرمج
انا فضلت العمل بطريقتين هنا
اذا ود المبرمج ان يحدد كل الحقول فعليه ان يختار المعامل *
و اذا ود اختيار مجموع من الحقول فقط فعليه ادخال اسماء الحقول فقط ضمن مصفوفة بسيط (مصفوفة من ثاني
)نسيت ان اشير الى جزئية هامة في الكود السابق و هي نوع بيانات الحقول القادمة من SQL SERVER يتم تحويلها الى انواع تتوافق مع اطار العمل
انا قمت بتحويل بعض الانواع فقط لذا يمكنك ان تقوم بتوسيع عملية التحويل حسب رغبتك
يتبع.............
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال


