منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب
صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - نسخة قابلة للطباعة

+- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb)
+-- قسم : قسم لغة الفيجوال بيسك VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=182)
+--- قسم : قسم مقالات VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=184)
+--- الموضوع : صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER (/showthread.php?tid=16247)

الصفحات: 1 2


صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16

بسم الله الرحمن الرحيم
الغاية من الفكرة هي تعليمية بحته و مشاركات الاراء 
الغالبية العظمى منا تملك كما كبيرا من الملعلومات في شتى الاختصاصات  و انا اراهن بكل ما عندي  الاغلب هنا هو محترف 
و لديه من المعلومات ما يكفيه لان ينتج برنامج كامل متكامل لا يعيبه شيئ ؟؟؟؟  Cool
ما دخل هذا الكلام بالموضوع ؟؟
سبب هذا الكلام هو ان اغلب المبرمجين ليس فقط هنا بل بشكل عام اعتادوا على قراءة المواضيع و طرح الاسئلة و من ثم السلام
بمعنى نحن نقرأ المواضيع و نناقش و نكتب و نجيب لمجرد العادة (اي اعتدنا على ذلك) ترى السائل في كثير من الاحيان يملك الاجابة في داخله
لكنه لا يستطيع الوصول اليها ضمن طيات الدماغ  Rolleyes يجرب و يجرب دون الوصول الى شيئ
السؤال من اين اتت الاجابة الى دماغ السائل بكل بساطة لقد قرأ في يوم من الايام موضوع او اجابة على نفس السؤال و لكن قراءة سريعة و السلام
الكثير من المقالات و الشروحات وضعت هنا و هناك لتاخذ بيدك الى الطريق الصحيح لكيفية استخدام تقنية ما و رغم قرائتنا لها و اعجابنا بها نحن نتجاهلها او نخاف منها مع اول تطبيق نقوم بصناعته و ذلك لقلة الخبرة في التعامل معها لذا نرى الاكواد قد ملئت النماذج من كل صنف و لون اجراء هنا و طريقة هناك و مصفوفة مكررة و معادة و  متغيرات و كائنات ما زالت عالقة في انتظار ان تتخلص منها او تعيدها الى موطنها و البرنامج بطيئ و السلوك العام للبرنامج في اسوء حال و المعالج يركض و لا يلحق (الحمد لله ان سرع المعالجات كبيرة لتغطي على عيوبنا)  Big Grin
انا لا استثني نفسي طبعا لست دائما اعمل بالطريقة الصحيحة و السبب ان الفكرة تبدأ بسيطة و من ثم تكبر و تكبر و يصبح عدد الاكواد و حجم البرنامج عائق امام اعادة التفكير بالطريقة الصحيحة (ناتج عن الكسل طبعا) , لذا دائما و ابدا استخدم تحليل البرنامج و سجل كل خطواتك من اصغر شيئ لاكبر شيئ حتى لو استغرق ذلك منك شهر بكامله ؟؟؟
نعم حتى لو كان شهر لا تتسرع و تكتب الاكواد قبل ان تكتمل لديك على الاقل 90% من الافكار الخاصة بالبرنامج
بعد اكتمال الافكار لديك توجه و اختر الطريقة الصحيحة و المنهجية التي تستخدم في البرامج العالمية لكتابة فئاتك الخاصة و تنظيمها بشكل مثالي يختصر عليك عمليات التكرار و عمليات التصحيح في المستقبل كما يجعل مشروعك قابل للفهم من الغير
استخدم اي تقنية تراها مناسبة و تؤدي عملك و نصيحتي لا تنظر الى من يقول لك هذه تقنية قديمة و عفى عليها الدهر ما دامت التقنية التي تستخدمها تؤدي الغرض المنوط بها بشكل سليم. طبعا هذا ليس تشجيعا لك بالابتعاد عن التقنيات الحديثة بل اردت ان اوضح فكرة مفادها انك اذا لم تتعامل مع التقنية الحديثة من قبل و اردت استخدامها الان دون الخوض بها سابقا فاعرف انك ستفشل فشلا ذريعا.
نحن منذ اعوام كثيرة و نحن نركض وراء التقنيات و كلما ظهرت تقنية جديدة نقفز اليها و نحاول فهما و اتقانها و التعامل معها و ما تكاد تلم ببعض تفاصيلها حتى تظهر تقنية اخرى تلغي ما قبلها بنظر المبرمجين و ليس بنظر الشركات المنتجة عندها ستجد نفسك تلاحق سرابا و تكره الساعة التي تعلمت فيها البرمجة   Big Grin
الكثير من البرامج المعمولة بتقنيات قديمة ما زالت تستخدم و بكثرة و على مستوى عالمي و تؤدي عملها بشكل مذهل ؟؟؟
لذا لا يحبطك وجود تقنية حديثة من عدمها المهم في الامر ان تكون قادر على انتاج برنامج يؤدي المطلوب دون تذمر الشاري (الزبون) لان الزبون لا يهتم بالتقنية و لا المبرمج ايضا  Big Grin كل ما يهمه هو ان يعمل البرنامج و ينظم له عمله على اتم وجه.
يتبع.....


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16

تقديم لفكرة الكلاس
الغاية من تصميم هذا الكلاس هي للاتصال بـ SQL SERVER و من ثم الحصول على قواعد البيانات فيه
و التعامل مع قاعدة يحددها المبرمج و استجلاب جداولها او اي جدول تحدده انت
و من ثم استجلاب كل حقول الجدول او الحقول التي تحددها انت
ومن ثم عمل خصائص للحقول للتعامل معها من حيث الاضافة و الحذف و التعديل
ملاحظة: للذين يعملون مع برامج قواعد البيانات الخاصة بـ SQL SERVER الكل يعرف انني اذا اردت التعامل مع جدول ما من خلال برنامجي فان هناك العديد من الطرق منها 
يحبذ البعض كتابة نص الاتصال الى القاعدة المحددة و من ثم كتابة جمل الاستعلام الخاصة به لجلب البيانات و من ثم التعامل مع كائنات لغة البرمجة التي تستقبل جمل استعلام SQL و من ثم تنفيذ هذه الجمل سواء كانت للاضافة او الحذف او التعديل
و البعض الاخر يعمل وفق تقنيات حديثة تقضي بعمل كائن مشابه للجدول او القاعدة (اقصد هنا تقنية التعامل مع لغة Linq) و يكون هذا الكائن بالاساس مشابه للاصل و لكن ضمن وحدة برمجية Class و ضمن هذا الكلاس يتم فرض هيكلية كاملة للقاعدة بكل ما تحويه من جداول و علاقات و حقول و اجراءات و وظائف  و كل شيئ
و فق خصائص و طرق عندها تصبح هذه الوحدة تحتوي على كائنات معرفة بشكل مستقل ضمن اللغة (كما كان يحدث مع تقنية المعالج) عند هذه النقطة يمكن للمبرمج ان يستغني عن تقنية SQL و يتخاطب مع الكائنات الجديدة وفق لغة خاصة Linq اذا ان الوصول للكائنات الجديدة اصبح متاح و بشكل يسير كوننا قمنا بتعريفها ضمن فئات خاصة لذا ستجد ان محرر الكود سيدعم لك الوصول السريع لهذه الكائنات , كل هذا جميل و رائع لكن توقف لحظة ما الذي سيجري في الخلفية من سيتخاطب مع القاعدة و باي لغة ؟؟ لا تتعب نفسك اخي الكريم القاعدة لا تفهم الا لغة واحدة SQL الفرق الوحيد انك لن تحتاج الى تعلم SQL اذا ما كنت جاهلا بها سيتكفل محرك اللغة بالقيام باي عمليات خاصة مع القاعدة وفق SQL (عود على بدء).

لكي تتضح الامور اكثر سنقوم بالشرح وفق كل كود سنتعامل معه و ستتوفر لدينا الكثير من المعلومات الجيدة اذا كنت تنوي المتابعة معي و ستفهم آلية العمل بشكل مفصل يمكنك من توسيع الكلاس الذي سنقوم بعمله هنا لناسب حاجتك.

اولا قم بانشاء مشروع جديد من النوع Class Library
ثم سميه ServSite او اي اسم يعجبك هذا الاسم اخترته لان هناك جزئية تختص بالسيرفر ربما اذا توفر لدي الوقت ساتكلم عنه لاحقا
الان اصبح لديك Class جديد في المشروع اسمه ServSite
هذا الكلاس ساستخدمه للاتصال بالسيرفر لجلب السيرفرات المثبته على الجهاز و تاسيس الاتصال مع السيرفر المطلوب و من ثم جلب القواعد و تاسيس اتصال مع قاعدة محددة و استجلاب جداولها و التعامل مع جدول محدد فقط.
و سيكون لدي كلاس اخر في المشروع يختص بالعمليات على قواعد البيانات سيرث خصائص من الكلاس السابق ServSite

في البداية اذا كنت لم تتطلع على هذا الموضوع هنا الغزل مع SQL SERVER
انصحك بقرائته لانني قمت بشرحه بشكل مفصل لتعرف طريقة الاتصال باي سيرفرات مثبته على الجهاز



مادامت الاكواد تخدمني لعمل اتصال باي سيرفر و تاسيس اتصال معه و مع القواعد داخله لذا فليس من المنطقي ان اقوم بتجاهل هذه الميزة
و الاتجاه الى الطرق اليدوية للاتصال بالسيرفر سواء عن طريق الاعدادت او التعامل مع الملفات النصية

في بداية الكلاس و بعد قرائتك للموضوع السابق سنستورد بعض المراجع للتعامل معها
PHP كود :
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft
.SqlServer.Management.Smo
Imports Microsoft
.Win32
Imports System
.Data.SqlClient
Public Class ServSite 

و ساعرف مجموع من الكائنات التي ساحتاجها ان وضعت الشرح في داخل الكود مع كل كائن

PHP كود :
   ''' <summary>
    ''' 
متغير من النوع سيرفر
    
''' نستخدمه للتعامل مع السيرفر
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared Srv As New Server

    ''' 
<summary>
 
   ''' متغير من النوع اتصالات السيرفر
    ''' 
نستخدمه لتمرير اتصال للسيرفر
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared srvcon As New ServerConnection

    
''' <summary>
    ''' 
متغير من النوع اتصالات السيكوال نستخدمه للاتصال بقاعدة البيانات
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared SqlConnection As New SqlConnection

    
''' <summary>
    ''' 
مصفوفة لتخزين اسماء السيرفرات
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared SrvNameArray() As String

    
''' <summary>
    ''' 
مصفوفة لتخزين اسماء قواعد البيانات
    
''' نستثني قواعد بيانات النظام
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared srvdbnames() As String

    ''' 
<summary>
 
   ''' مصفوفة لتخزين اسماء الجداول في القاعدة المحددة
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared TablesSrvDbs() As String

    ''' 
<summary>
 
   ''' متغير نصي نخزن فيه اسم القاعدة المحددة
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared SqlDbName As String

    ''' 
<summary>
 
   ''' متغير نصي نخزن فيه نص الاتصال مع قاعدة البيانات
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared _SqlConnectionString As String 

بالنسبة للجزئية الخاصة  XML Tags for Documentation  الظاهرة ضمن الاكود اذا ما لم تتعامل معها سابقا
ساقول لك بانها طريقة جميلة للتعليق على الوظائف  و معرفة الغرض منها اثناء اعادة استخدامها .
الفائدة منها تاتي عند تعريفك للكائن في وحدة برمجية جديدة ستاتيك المعلومات المرافقة للكائن و التي كنت قد كتبتها سابقا تمام كما يحصل مع اي كائنات ضمن اللغة عندما يقف عليها المؤشر 
الجميل فيها ايضا يمكنك تمرير معلومات تفصيلية عن البارمترات التي تريد تمريرها كذلك وضع ملاحظات مفصلة كما تحب و كلها ضمن Tag Xml واحد


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16

الان ناتي الى الاستفادة من الكائنات التي عرفناها مسبقا و نحول ملئها بالمعومات المفيدة
اولا لنحصل السيرفرات المثبته بالجهاز و فق الاجراء التالي
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بالبحث عن السيرفرات المثبتة على الجهاز
    
'''  و اضافتها الى مصفوفة السيرفرات ويعيد نص اتصال مع السيرفر
    ''' 
</summary>
 
   ''' <returns>يعود بقيمة نصية تمثل اسم السيرفر الاخير</returns>
    ''' 
<remarks>بامكانك استخدام مربع نص او قائمة لاستقبال المخرجات</remarks>
 
   Private Shared Function LoadServ() As String
        Dim Machine 
As String Nothing
        Dim rk 
As RegistryKey Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server")
 
       Dim instances As [String]() = DirectCast(rk.GetValue("InstalledInstances"), [String]())
 
       If instances.Length 0 Then
            For Each element 
As [StringIn instances
                If element 
"MSSQLSERVER" Then
                    Machine 
= (System.Environment.MachineName)
 
                   ReDim SrvNameArray(instances.Length 1)
 
                   instances.CopyTo(SrvNameArray0)
 
               Else
                    Machine 
= (System.Environment.MachineName "\" + element)
                    ReDim SrvNameArray(instances.Length - 1)
                    instances.CopyTo(SrvNameArray, 0)

                End If
            Next

        End If
        srvcon = New ServerConnection(Machine)
        Srv = New Server(srvcon)
        Return Machine
    End Function 

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

بعد ان توفرنا على السيرفر اصبح بامكاننا الحصول على قواعد البيانات بداخله و اضافتها الى مصفوفة قواعد البيانات لدينا
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بتحميل قواعد البيانات في السيرفر المحدد
    
''' واضافتها الى مصفوفة القواعد
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Private Shared Sub loaddbnames()
        Dim db As New Database
        Dim j As Integer = 0
        For i = 0 To Srv.Databases.Count - 1
            If Not Srv.Databases(i).IsSystemObject And Not ((Srv.Databases(i).Name = "")) Then
                ReDim Preserve srvdbnames(j)
                db.Name = Srv.Databases(i).Name
                srvdbnames.SetValue(db.Name, j)
                j += 1
            End If
        Next
    End Sub 

و كذلك ايضا تحميل الجداول في القاعدة المحددة الى مصفوفة الجداول .
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بتحميل جداول القاعدة المحددة
    
''' و اضافتها الى مصفوفة الجداول
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Private Shared Sub LoadTablenames()

        If Not (SqlDbName Is Nothing) Or SqlDbName = "" Then
            Dim Dbs As Database = Srv.Databases(SqlDbName)
            ReDim TablesSrvDbs(Dbs.Tables.Count)
            For i = 0 To Dbs.Tables.Count - 1
                If Not Dbs.Tables(i).IsSystemObject Then
                    TablesSrvDbs.SetValue(Dbs.Tables(i).Name, i)
                End If
            Next
        End If

    End Sub 

الاجراء الخاص بتاسيس اتصال مع القاعدة المحددة مشروح بالتفصيل ضمن الكود
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بتاسيس الاتصال مع القاعدة المحددة
    
''' و يحتاج الى بارميتر نصي يمثل اسم القاعدة
    ''' 
</summary>
 
   ''' <param name="Dbname">اسم قاعدة البيانات كنص</param>
    ''' 
<returns>يعود بقيمة نصية تمثل نص الاتصال</returns>
 
   ''' <remarks></remarks>
    Public Shared Function SetConnectionString_ForDb(ByVal Dbname As String) As String
        '
فحص طول مصفوفة السيرفرات
        If SrvNameArray
.Length <= 0 Then
            LoadServ
()
 
       End If
 
       'فحص طول مصفوفة القواعد
        If srvdbnames.Length <= 0 Then
            loaddbnames()
        End If

        '
التاكد من وجود سيرفرات على الجهاز من خلال مصفوفة السيرفرات
        If srvdbnames
.Length <= 0 Then
            Return MsgBox
("تاكد من وجود سيرفرات على الجهاز", , "From SetConnectionString_ForDb")
 
           Exit Function
 
       End If
 
       'التاكد من وجود قواعد على السيرفر من خلال مصفوفة القواعد
        If srvdbnames.Length <= 0 Then
            Return MsgBox("تاكد من وجود قواعد على السيرفر", , "From SetConnectionString_ForDb")
            Exit Function
        End If
        '
الحصول على اسم اخر سيرفر
        Dim PcName 
As String LoadServ()
 
       'حلقة لفحص وجود القاعدة المحددةفي مصفوفة القواعد
        '
ثم اسنادها الى المتغير العام الذي يمثل اسم القاعدة
        
'ثم تحميل الجداول الموجودة في القاعدة الى مصفوفة الجداول
        '
و العودة بنص الاتصال مع القاعدة المحددة
        For i 
As Integer 0 To srvdbnames.Length 1
            If 
(Dbname srvdbnames(i)) Then
                SqlDbName 
Dbname
                LoadTablenames
()
 
               Return "Data Source=" PcName ";" "Database=" SqlDbName ";" _
                 
"Integrated Security=true;"
 
           End If
 
       Next
        
'عرض رسالة في حال عدم تواجد القاعدة و اغلاق الاجراء
        If SqlDbName = "" Then
            Return MsgBox("القاعدة غير موجودة ضمن السيرفر", , "From SetConnectionString_ForDb")
            Exit Function
        End If
        '
العودة بنص الاتصال مع القاعدة المحددة
        Return 
"Data Source=" PcName ";" "Database=" SqlDbName ";" _
               
"Integrated Security=true;"
 
   End Function 


الان اجراء يقوم بفتح الاتصال مع القاعدة المحددة وفق رغبتنا مع الشرح
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بفتح الاتصال مع قاعدة البيانات المحددة
    
''' </summary>
    ''' 
<returns>يعيد قيمة نصية تمثل حالة الاتصال</returns>
 
   ''' <remarks></remarks>
    Public Shared Function OpenSqlConnection() As String
        '
فحص حالة الاتصال
        If SqlConnection
.State ConnectionState.Closed Then
            
'ربط الاتصال مع القاعدة المحددة
            _SqlConnectionString = SetConnectionString_ForDb(SqlDbName)
            '
اسناد نص الاتصال الى كائن الاتصال
            SqlConnection
.ConnectionString _SqlConnectionString
            
'فتح الاتصال
            SqlConnection.Open()
        End If
        '
العودة بقيمة توضح حالة الاتصال
        Return SqlConnection
.State.ToString
    End 
Function 

و اخيرا و ليس اخرا غلق الاتصال مع القاعدة
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بغلق الاتصال مع قاعدة البيانات
    
''' </summary>
    ''' 
<returns>يعيد قيمة نصية تمثل حالة الاتصال</returns>
 
   ''' <remarks></remarks>
    Public Shared Function CloseSqlConnection() As String
        '
فحص حالة الاتصال اذا كان مفتوح يتم اغلاقه
        If SqlConnection
.State ConnectionState.Open Then
            SqlConnection
.Close()
 
       End If
 
       'العودة بقيمة توضح حالة الاتصال
        Return GetConnectionState()
    End Function 

الان سنقوم بعمل بعض الخصائص التي تفيدنا اثناء عملنا
مذا لو احتجت الى كائن الاتصال و معلومات عنه الا يجب ان يكون لدينا طريقة للوصول اليه , نعم بكل تاكيد 
اليك هذه الخاصية للوصول اليه
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط تعيد كائن اتصال
    
''' </summary>
    ''' 
<value>القيمة هي كائن اتصال</value>
 
   ''' <returns>يعيد كائن اتصال</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetSqlConnection() As SqlConnection
        Get
            Return SqlConnection
        End Get
    End Property 

و كذلك لما لا نعيد نص الاتصال يمكن نحتاجه
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط
    
''' تعيد نص الاتصال
    ''' 
</summary>
 
   ''' <value>القيمة المعادة تمثل نص الاتصال</value>
    ''' 
<returns>القيمة المعادة تمثل نص الاتصال</returns>
 
   ''' <remarks></remarks>
    Shared ReadOnly Property GetSQlConnectionString() As String
        Get
            Return "Connection String : " & _SqlConnectionString
        End Get
    End Property 

مع انه يمكننا الحصول على حالة الاتصال بس زيادة الخير خير
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط
    
''' تعيد حالة الاتصال
    ''' 
</summary>
 
   ''' <value>القيمة المعادة تمثل حالة الاتصال</value>
    ''' 
<returns>القيمة المعادة تمثل حالة الاتصال</returns>
 
   ''' <remarks></remarks>
    Shared ReadOnly Property GetConnectionState As String
        Get
            Return "Connection State Is : " & SqlConnection.State.ToString
        End Get
    End Property 

و كمان يمكن نحتاج لاسم السيرفر خلي الكلاس يصير شوربة  Big Grin
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط  تعيد اسم السيرفر المستخدم
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل اسم السيرفر</value>
 
   ''' <returns>القيمة المعادة تمثل اسم السيرفر</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetSrvName As String
        Get
            Return 
"Server Name : " Srv.Name
        End Get
    End Property 

و كمان ايضا لدي خطة لاعادة اسماء السيرفرات و اسماء  قواعد البيانات  و اسماء الجداول في السيرفر لانني ساحتاجها لاحقا ... ساخبرك لاحقا!!!!

السيرفرات
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط تعيد نص يمثل اسماء السيرفرات
    
''' </summary>
    ''' 
<value>القيمة المعادة نص يمثل اسماء السيرفرات</value>
 
   ''' <returns>القيمة المعادة نص يمثل اسماء السيرفرات</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property ShowServersNames() As String
        Get
            Dim SrvN 
As String ""
 
           For i As Integer 0 To SrvNameArray.Length 1
                SrvN 
+= SrvNameArray.GetValue(i) & vbCrLf
            Next

            Return SrvN
        End Get
    End Property 

القواعد
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط تعيد اسماء القواعد في السيرفر
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</value>
 
   ''' <returns>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetDbNames() As String
        Get
            Dim DbName 
As String ""
 
           For i As Integer 0 To srvdbnames.Length 1
                DbName 
+= srvdbnames.GetValue(i) & vbCrLf
            Next
            Return DbName
        End Get
    End Property 

الجداول
PHP كود :
   ''' <summary>
    ''' 
خاصية للقراءة فقط تعيد اسماء الجداول في القاعدة المحددة
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</value>
 
   ''' <returns>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</returns>
    ''' 
<remarks></remarks>
 
   Public Shared ReadOnly Property GetTablesName() As String
        Get
            Dim Tablename 
As String ""
 
           For i As Integer 0 To TablesSrvDbs.Length 1
                Tablename 
+= TablesSrvDbs.GetValue(i) & vbCrLf
            Next

            Return Tablename
        End Get
    End Property 

و هذا كود الكلاس كامل منظم
PHP كود :
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft
.SqlServer.Management.Smo
Imports Microsoft
.Win32
Imports System
.Data.SqlClient
Public Class ServSite
    
''' <summary>
    ''' 
متغير من النوع سيرفر
    
''' نستخدمه للتعامل مع السيرفر
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared Srv As New Server

    ''' 
<summary>
 
   ''' متغير من النوع اتصالات السيرفر
    ''' 
نستخدمه لتمرير اتصال للسيرفر
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared srvcon As New ServerConnection

    
''' <summary>
    ''' 
متغير من النوع اتصالات السيكوال نستخدمه للاتصال بقاعدة البيانات
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared SqlConnection As New SqlConnection

    
''' <summary>
    ''' 
مصفوفة لتخزين اسماء السيرفرات
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Protected Shared SrvNameArray() As String

    
''' <summary>
    ''' 
مصفوفة لتخزين اسماء قواعد البيانات
    
''' نستثني قواعد بيانات النظام
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared srvdbnames() As String

    ''' 
<summary>
 
   ''' مصفوفة لتخزين اسماء الجداول في القاعدة المحددة
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared TablesSrvDbs() As String

    ''' 
<summary>
 
   ''' متغير نصي نخزن فيه اسم القاعدة المحددة
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared SqlDbName As String

    ''' 
<summary>
 
   ''' متغير نصي نخزن فيه نص الاتصال مع قاعدة البيانات
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Protected Shared _SqlConnectionString As String
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    ''' 
<summary>
 
   ''' اجراء يقوم بالبحث عن السيرفرات المثبتة على الجهاز
    ''' 
 و اضافتها الى مصفوفة السيرفرات ويعيد نص اتصال مع السيرفر
    
''' </summary>
    ''' 
<returns>يعود بقيمة نصية تمثل اسم السيرفر الاخير</returns>
 
   ''' <remarks>بامكانك استخدام مربع نص او قائمة لاستقبال المخرجات</remarks>
    Private Shared Function LoadServ() As String
        Dim Machine As String = Nothing
        Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server")
        Dim instances As [String]() = DirectCast(rk.GetValue("InstalledInstances"), [String]())
        If instances.Length > 0 Then
            For Each element As [String] In instances
                If element = "MSSQLSERVER" Then
                    Machine = (System.Environment.MachineName)
                    ReDim SrvNameArray(instances.Length - 1)
                    instances.CopyTo(SrvNameArray, 0)
                Else
                    Machine = (System.Environment.MachineName + "\" + element)
                    ReDim SrvNameArray(instances.Length - 1)
                    instances.CopyTo(SrvNameArray, 0)

                End If
            Next

        End If
        srvcon = New ServerConnection(Machine)
        Srv = New Server(srvcon)
        Return Machine
    End Function

    ''' 
<summary>
 
   ''' اجراء يقوم بتحميل قواعد البيانات في السيرفر المحدد
    ''' 
واضافتها الى مصفوفة القواعد
    
''' </summary>
    ''' 
<remarks></remarks>
 
   Private Shared Sub loaddbnames()
 
       Dim db As New Database
        Dim j 
As Integer 0
        For i 
0 To Srv.Databases.Count 1
            If Not Srv
.Databases(i).IsSystemObject And Not ((Srv.Databases(i).Name "")) Then
                ReDim Preserve srvdbnames
(j)
 
               db.Name Srv.Databases(i).Name
                srvdbnames
.SetValue(db.Namej)
 
               j += 1
            End 
If
 
       Next
    End Sub

    
''' <summary>
    ''' 
اجراء يقوم بتحميل جداول القاعدة المحددة
    
''' و اضافتها الى مصفوفة الجداول
    ''' 
</summary>
 
   ''' <remarks></remarks>
    Private Shared Sub LoadTablenames()

        If Not (SqlDbName Is Nothing) Or SqlDbName = "" Then
            Dim Dbs As Database = Srv.Databases(SqlDbName)
            ReDim TablesSrvDbs(Dbs.Tables.Count)
            For i = 0 To Dbs.Tables.Count - 1
                If Not Dbs.Tables(i).IsSystemObject Then
                    TablesSrvDbs.SetValue(Dbs.Tables(i).Name, i)
                End If
            Next
        End If

    End Sub

    ''' 
<summary>
 
   ''' اجراء يقوم بتاسيس الاتصال مع القاعدة المحددة
    ''' 
و يحتاج الى بارميتر نصي يمثل اسم القاعدة
    
''' </summary>
    ''' 
<param name="Dbname">اسم قاعدة البيانات كنص</param>
 
   ''' <returns>يعود بقيمة نصية تمثل نص الاتصال</returns>
    ''' 
<remarks></remarks>
 
   Public Shared Function SetConnectionString_ForDb(ByVal Dbname As String) As String
        
'فحص طول مصفوفة السيرفرات
        If SrvNameArray.Length <= 0 Then
            LoadServ()
        End If
        '
فحص طول مصفوفة القواعد
        If srvdbnames
.Length <= 0 Then
            loaddbnames
()
 
       End If

 
       'التاكد من وجود سيرفرات على الجهاز من خلال مصفوفة السيرفرات
        If srvdbnames.Length <= 0 Then
            Return MsgBox("تاكد من وجود سيرفرات على الجهاز", , "From SetConnectionString_ForDb")
            Exit Function
        End If
        '
التاكد من وجود قواعد على السيرفر من خلال مصفوفة القواعد
        If srvdbnames
.Length <= 0 Then
            Return MsgBox
("تاكد من وجود قواعد على السيرفر", , "From SetConnectionString_ForDb")
 
           Exit Function
 
       End If
 
       'الحصول على اسم اخر سيرفر
        Dim PcName As String = LoadServ()
        '
حلقة لفحص وجود القاعدة المحددةفي مصفوفة القواعد
        
'ثم اسنادها الى المتغير العام الذي يمثل اسم القاعدة
        '
ثم تحميل الجداول الموجودة في القاعدة الى مصفوفة الجداول
        
'و العودة بنص الاتصال مع القاعدة المحددة
        For i As Integer = 0 To srvdbnames.Length - 1
            If (Dbname = srvdbnames(i)) Then
                SqlDbName = Dbname
                LoadTablenames()
                Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _
                 & "Integrated Security=true;"
            End If
        Next
        '
عرض رسالة في حال عدم تواجد القاعدة و اغلاق الاجراء
        If SqlDbName 
"" Then
            Return MsgBox
("القاعدة غير موجودة ضمن السيرفر", , "From SetConnectionString_ForDb")
 
           Exit Function
 
       End If
 
       'العودة بنص الاتصال مع القاعدة المحددة
        Return "Data Source=" & PcName & ";" & "Database=" & SqlDbName & ";" _
               & "Integrated Security=true;"
    End Function

    ''' 
<summary>
 
   ''' اجراء يقوم بفتح الاتصال مع قاعدة البيانات المحددة
    ''' 
</summary>
 
   ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns>
    ''' 
<remarks></remarks>
 
   Public Shared Function OpenSqlConnection() As String
        
'فحص حالة الاتصال
        If SqlConnection.State = ConnectionState.Closed Then
            '
ربط الاتصال مع القاعدة المحددة
            _SqlConnectionString 
SetConnectionString_ForDb(SqlDbName)
 
           'اسناد نص الاتصال الى كائن الاتصال
            SqlConnection.ConnectionString = _SqlConnectionString
            '
فتح الاتصال
            SqlConnection
.Open()
 
       End If
 
       'العودة بقيمة توضح حالة الاتصال
        Return SqlConnection.State.ToString
    End Function

    ''' 
<summary>
 
   ''' اجراء يقوم بغلق الاتصال مع قاعدة البيانات
    ''' 
</summary>
 
   ''' <returns>يعيد قيمة نصية تمثل حالة الاتصال</returns>
    ''' 
<remarks></remarks>
 
   Public Shared Function CloseSqlConnection() As String
        
'فحص حالة الاتصال اذا كان مفتوح يتم اغلاقه
        If SqlConnection.State = ConnectionState.Open Then
            SqlConnection.Close()
        End If
        '
العودة بقيمة توضح حالة الاتصال
        Return GetConnectionState
()
 
   End Function

 
   ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#Region "Propertes"

 
   ''' <summary>
    ''' 
خاصية للقراءة فقط تعيد كائن اتصال
    
''' </summary>
    ''' 
<value>القيمة هي كائن اتصال</value>
 
   ''' <returns>يعيد كائن اتصال</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetSqlConnection() As SqlConnection
        Get
            Return SqlConnection
        End Get
    End Property

    
''' <summary>
    ''' 
خاصية للقراءة فقط
    
''' تعيد نص الاتصال
    ''' 
</summary>
 
   ''' <value>القيمة المعادة تمثل نص الاتصال</value>
    ''' 
<returns>القيمة المعادة تمثل نص الاتصال</returns>
 
   ''' <remarks></remarks>
    Shared ReadOnly Property GetSQlConnectionString() As String
        Get
            Return "Connection String : " & _SqlConnectionString
        End Get
    End Property

    ''' 
<summary>
 
   ''' خاصية للقراءة فقط
    ''' 
تعيد حالة الاتصال
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل حالة الاتصال</value>
 
   ''' <returns>القيمة المعادة تمثل حالة الاتصال</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetConnectionState As String
        Get
            Return 
"Connection State Is : " SqlConnection.State.ToString
        End Get
    End Property

    
''' <summary>
    ''' 
خاصية للقراءة فقط  تعيد اسم السيرفر المستخدم
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل اسم السيرفر</value>
 
   ''' <returns>القيمة المعادة تمثل اسم السيرفر</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetSrvName As String
        Get
            Return 
"Server Name : " Srv.Name
        End Get
    End Property

    
''' <summary>
    ''' 
خاصية للقراءة فقط تعيد اسماء القواعد في السيرفر
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</value>
 
   ''' <returns>القيمة المعادة تمثل نص يحمل اسماء القواعد في السيرفر</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property GetDbNames() As String
        Get
            Dim DbName 
As String ""
 
           For i As Integer 0 To srvdbnames.Length 1
                DbName 
+= srvdbnames.GetValue(i) & vbCrLf
            Next
            Return DbName
        End Get
    End Property

    
''' <summary>
    ''' 
خاصية للقراءة فقط تعيد اسماء الجداول في القاعدة المحددة
    
''' </summary>
    ''' 
<value>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</value>
 
   ''' <returns>القيمة المعادة تمثل نص يحمل اسماء الجداول في القاعدة المحددة</returns>
    ''' 
<remarks></remarks>
 
   Public Shared ReadOnly Property GetTablesName() As String
        Get
            Dim Tablename 
As String ""
 
           For i As Integer 0 To TablesSrvDbs.Length 1
                Tablename 
+= TablesSrvDbs.GetValue(i) & vbCrLf
            Next

            Return Tablename
        End Get
    End Property

    
''' <summary>
    ''' 
خاصية للقراءة فقط تعيد نص يمثل اسماء السيرفرات
    
''' </summary>
    ''' 
<value>القيمة المعادة نص يمثل اسماء السيرفرات</value>
 
   ''' <returns>القيمة المعادة نص يمثل اسماء السيرفرات</returns>
    ''' 
<remarks></remarks>
 
   Shared ReadOnly Property ShowServersNames() As String
        Get
            Dim SrvN 
As String ""
 
           For i As Integer 0 To SrvNameArray.Length 1
                SrvN 
+= SrvNameArray.GetValue(i) & vbCrLf
            Next

            Return SrvN
        End Get
    End Property

#End Region

End Class 



RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16

ناتي الان للمفيد و الشغل الجامد
الكلاس الثاني في مشروعنا هو كلاس التعامل مع قاعدة البيانات (الحذف و التعديل و الاضافة) 
بس؟؟؟؟
بس و الباقي عليك انت؟؟
وجهة نظري تقول اذا كنت قد حصلت على اتصال مع السرفر و حددت القاعدة و الجدول الذي اريده و لدي ايضا كل الحقول التي اريدها
لماذا لا يكون لدي جمل استعلام ديناميكية تقوم لوحدها بتركيب نفسها اعتمادا على مدخلات بسيطة مني 
فقط انا امرر اسماء الحقول و هي تقوم بعمل جمل (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(20)

 
   ''' <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(40 '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(kyes0kyes.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(2cs)
 
           Column.SetValue(dc.Name0cs)

 
           Select Case (dc.DataType.SqlDataType)
 
               Case Is SqlDataType.NVarChar
                    Column
.SetValue(SqlDbType.NVarChar1cs)
 
                   InsUpSel.SetValue(SqlDbType.NVarChar1cs)
 
                   DTc.DataType System.Type.GetType("System.String")
 
               Case Is SqlDataType.VarChar
                    Column
.SetValue(SqlDbType.VarChar1cs)
 
                   InsUpSel.SetValue(SqlDbType.VarChar1cs)
 
                   DTc.DataType System.Type.GetType("System.String")
 
               Case Is SqlDataType.NChar
                    Column
.SetValue(SqlDbType.NChar1cs)
 
                   InsUpSel.SetValue(SqlDbType.NChar1cs)
 
                   DTc.DataType System.Type.GetType("System.String")
 
               Case Is SqlDataType.Int
                    Column
.SetValue(SqlDbType.Int1cs)
 
                   InsUpSel.SetValue(SqlDbType.Int1cs)
 
                   DTc.DataType System.Type.GetType("System.Int32")
 
               Case Is SqlDataType.Date
                    Column
.SetValue(SqlDbType.Date1cs)
 
                   InsUpSel.SetValue(SqlDbType.Date1cs)
 
                   DTc.DataType System.Type.GetType("System.DateTime")
 
               Case Is SqlDataType.DateTime
                    Column
.SetValue(SqlDbType.DateTime1cs)
 
                   InsUpSel.SetValue(SqlDbType.DateTime1cs)
 
                   DTc.DataType System.Type.GetType("System.DateTime")
 
               Case Is SqlDataType.Float
                    Column
.SetValue(SqlDbType.Float1cs)
 
                   InsUpSel.SetValue(SqlDbType.Float1cs)
 
                   DTc.DataType System.Type.GetType("System.Double")
 
               Case Is SqlDataType.Image
                    Column
.SetValue(SqlDbType.Image1cs)
 
                   InsUpSel.SetValue(SqlDbType.Image1cs)
 
                   DTc.DataType System.Type.GetType("System.Byte")
 
               Case Is SqlDataType.Decimal
                    Column
.SetValue(SqlDbType.Decimal1cs)
 
                   InsUpSel.SetValue(SqlDbType.Decimal1cs)
 
                   DTc.DataType System.Type.GetType("System.Decimal")
 
           End Select
            InsUpSel
.SetValue("@" dc.Name2cs)

 
           If dc.InPrimaryKey Then
                Column
.SetValue("prim"2cs)
 
               InsUpSel.SetValue("prim"3cs)
 
               '
                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 

بعد ان تم ملئ المصفوفات بالبيانات اللازمة جاء دور العمل مع جمل الاستعلام الديناميكية و الاستفادة من كل المعلومات السابقة لاستخلاص جملة تحديد مناسبة على ذوق المبرمج
انا فضلت العمل بطريقتين هنا
اذا ود المبرمج ان يحدد كل الحقول فعليه ان يختار المعامل * 
و اذا ود اختيار مجموع من الحقول فقط فعليه ادخال اسماء الحقول فقط ضمن مصفوفة بسيط (مصفوفة من ثاني  Sad )
نسيت ان اشير الى جزئية هامة في الكود السابق و هي نوع بيانات الحقول القادمة من SQL SERVER يتم تحويلها الى انواع تتوافق مع اطار العمل
انا قمت بتحويل بعض الانواع فقط لذا يمكنك ان تقوم بتوسيع عملية التحويل حسب رغبتك 
يتبع.............


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 25-06-16

الان مع جملة التحديد ,سنبدأ الاستفادة من كل المعلومات التي قمنا بتخزينها سابقا
سنقوم بعمل جملة تحديد بسيطة نعبئ فيها الحقول من مصفوفة الحقول التي انشأناها سابقا وفق حلقة تكرارية 
و سنفحص اذا ما كان الحقل هو مفتاح رئيسي في قائمة الحقول لنضيفه الى جملة التحديد ايضا
و كذلك سنضيف قائمة البارمترات المرافقة للحقول من المصفوفة الموافقة الى كائن SQL COMMAND
توقف اخي ؟؟؟ لماذا ساضيف بارمترات مع جملة التحديد
ربما تحتاجها مستقبلا اذا ما نويت التوسع في الكلاس كان تجري عمليات بحث و فلترة و غيرها من الامور المعتمدة على البارمترات
الكود التالي يوضح العملية مع الشرح
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بانشاء جملة تحديد لبيانات الجدول المحدد
    
''' يمكنك تحديد كل حقول الجدول بواسطة 
    ''' 
علامة في مصفوفة الحقول
    
''' او تحديد الحقول التي تريدها
    ''' 
</summary>
 
   ''' <param name="Command">كائن الكوماند</param>
    ''' 
<param name="Columns">مصفوفة نصية تحتوي على الحقول</param>
 
   ''' <returns>يعود بكائن كوماند يحمل جملة التحديد</returns>
    ''' 
<remarks></remarks>
 
   Private Function Create_Select_For_Command(ByVal Command As SqlCommandByVal ParamArray Columns() As String) As SqlCommand

        If _TableName 
"" Or _TableName Is Nothing Then
            MsgBox
("حدد اسم الجدول اولا", , "From Create_Select_For_Command")
 
           Return Nothing
            Exit 
Function
 
       End If
 
       '**********************************************

        Dim SelectColumns As String = "Select " '
"("
 
       Dim filed As String ""
 
       Dim sa As Integer 0
        Dim qf 
As Integer 0
        Dim qfiled 
As String ""
 
       '-----------------------------------
        Command.Connection = GetSqlConnection
        '
 
       If Columns(0) = "*" Then

            For ic 
0 To InsUpSel.GetLength(1) - 1
                If qf 
InsUpSel.GetLength(1) - 1 Then
                    qfiled 
+= InsUpSel(0ic)
 
               Else
                    qfiled 
+= InsUpSel(0ic) & ","
 
               End If
 
               qf += 1
            Next
            SelectColumns 
+= qfiled " From " _TableName
            qfiled 
""
 
           qf 0


        ElseIf Columns
(0) <> "*" And Columns.Length >= 0 Then
            Columns 
Columns
            If checkfileds
(Columns) = True Then
                Return Nothing
                Exit 
Function
 
           End If

 
           For Each Str As String In Columns
                For ic 
0 To InsUpSel.GetLength(1) - 1
                    If Str 
InsUpSel(0icThen
                        If qf 
Columns.Length 1 Then
                            qfiled 
+= InsUpSel(0ic)
 
                       Else
                            qfiled 
+= InsUpSel(0ic) & ","
 
                       End If
 
                   End If
 
               Next
                qf 
+= 1
            Next
            SelectColumns 
+= qfiled " From " _TableName
        End 
If
 
       '
        Command.CommandText = SelectColumns
        Return Command
    End Function 

اذا دققت في الكود السابق ستجد ان لديك الاجراء checkfileds
هذا الاجراء مهمته تفحص تواجد الحقول المدخلة من قبل المستخدم و مطابقتها مع مصفوفة الحقول لدينا
لكي لا يدخل المستخدم اسم حقل غير موجود لدينا
PHP كود :
   ''' <summary>
    ''' ''
اجراء يقوم بفحص الحقول الممرة وفق مصفوفة الحقول
    
''' ويختبر تواجدها في الجدول
    ''' 
</summary>
 
   ''' <param name="ColCheck">البارميتر هو مصفوفة من الحقول </param>
    Private Function checkfileds(ByVal ParamArray ColCheck() As String) As Boolean
        Dim flds(0) As String
        Dim check As Boolean
        For m = 0 To InsUpSel.GetLength(1) - 1
            ReDim Preserve flds(m)
            flds.SetValue(InsUpSel(0, m), m)

        Next

        For Each t As String In ColCheck
            If Not (flds.Contains(t)) Then
                MsgBox("لا يوجد حقل بالاسم(" & t & ") في الجدول(" & _TableName & ")", , "الرسالة قادمة من الاجراء  checkfileds")
                Return check = True
                Exit Function
            End If
        Next
        Return check
    End Function 

الان ننتقل الى UPDATE
عملية تحديث البيانات في القاعدة تعتمد على شيئ اساسي الا و هو عمود المفتاح الرئيسي اذا ان جملة التحديث تبقى عمياء بدون هذا الحقل ولا تعرف اي حقل تريد ان تحدث لذا وجب ان يكون البارميتر الخاص بهذا الحقل اساسي يعني يحمل القيمة الحقيقة 
عملية تحديد الحقول كما سابقها في جملة SELECT 
PHP كود :
   ''' <summary>
    ''' 'يقوم هذا الاجراء بانشاء جملة تحديث للجدول المحدد
    ''' 
و يقوم باسنادها الى الكوماند المطلوب
    
''' يحتاج الى بارميترين الاول هو كائن الكوماند
    ''' 
و الثاني هو مصفوفة الحقول بامكانك تمرير علامة في الاشارة الى كافة الحقول
    
''' او تمرير الحقول حسب الرغبة كما يلي
    ''' 
</summary>
 
   ''' <param name="Command">
    ''' 
كائن الكوماند
    
''' </param>
    ''' 
<param name="Columns">مصفوفة نصية تحتوي على اسماء الحقول</param>
 
   ''' <returns>يعود بكائن كوماند يحمل جملة التحديث</returns>
    ''' 
<remarks
 
   ''' </remarks>
    Private Function Create_update_For_Command(ByVal Command As SqlCommand, ByVal ParamArray Columns() As String) As SqlCommand
        If _TableName = "" Or _TableName Is Nothing Then
            MsgBox("حدد اسم الجدول اولا", , "From Create_update_For_Command ")
            Return Nothing
            Exit Function
        End If
        '
----------------------------------------------------------------
 
       Dim Updatest As String ""

 
       Dim qfiled As String ""
 
       Dim CurrentKey As String ""
 
       Dim OrginalKey As String ""
 
       Dim qf As Integer 0
        Dim qparm 
As New SqlParameter
        
'***********************************************
        Command.Connection = GetSqlConnection
        Command.Parameters.Clear()
        '
---------------------------------------------------------------------------------------
 
       '''''''''

        If Columns(0) = "*" Then
            For ic = 0 To InsUpSel.GetLength(1) - 1
                qparm = New SqlParameter
                If Not (InsUpSel(3, ic) = "prim") Then
                    If qf = InsUpSel.GetLength(1) - 1 Then
                        qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic)
                        qparm.ParameterName = InsUpSel(2, ic)
                        qparm.SqlDbType = InsUpSel(1, ic)
                        qparm.SourceColumn = InsUpSel(0, ic)
                        Command.Parameters.Add(qparm)
                    Else
                        qfiled += InsUpSel(0, ic) & "=" & InsUpSel(2, ic) & ","
                        qparm.ParameterName = InsUpSel(2, ic)
                        qparm.SqlDbType = InsUpSel(1, ic)
                        qparm.SourceColumn = InsUpSel(0, ic)
                        Command.Parameters.Add(qparm)


                    End If
                Else

                    CurrentKey = InsUpSel(0, ic)
                    OrginalKey = InsUpSel(2, ic)
                    qparm.ParameterName = InsUpSel(2, ic)
                    qparm.SqlDbType = InsUpSel(1, ic)
                    qparm.SourceColumn = InsUpSel(0, ic)
                    Command.Parameters.Add(qparm)
                    '''''''
 
                   qparm = New SqlParameter
                    qparm
.ParameterName "@Orginal_" InsUpSel(0ic)
 
                   qparm.SqlDbType InsUpSel(1ic)
 
                   qparm.SourceColumn InsUpSel(0ic)
 
                   qparm.SourceVersion DataRowVersion.Original
                    Command
.Parameters.Add(qparm)
 
               End If

 
               qf += 1
            Next
            Updatest 
"Update " _TableName " Set " qfiled "  Where " CurrentKey " = " OrginalKey
            
'
            qfiled = ""
            CurrentKey = ""
            OrginalKey = ""
            qf = 0
            '

 
       ElseIf Columns(0) <> "*" And Columns.Length >= 1 Then
            Columns 
Columns
            
'
            If checkfileds(Columns) = True Then
                Return Nothing
                Exit Function
            End If
            '
 
           For Each Str As String In Columns



                For ic 
0 To InsUpSel.GetLength(1) - 1
                    If Not 
(InsUpSel(3ic) = "prim"Then

                        If Str 
InsUpSel(0icThen
                            qparm 
= New SqlParameter
                            If qf 
Columns.Length 1 Then
                                qfiled 
+= InsUpSel(0ic) & "=" InsUpSel(2ic)
 
                               qparm.ParameterName InsUpSel(2ic)
 
                               qparm.SqlDbType InsUpSel(1ic)
 
                               qparm.SourceColumn InsUpSel(0ic)
 
                               Command.Parameters.Add(qparm)
 
                           Else
                                qfiled 
+= InsUpSel(0ic) & "=" InsUpSel(2ic) & ","
 
                               qparm.ParameterName InsUpSel(2ic)
 
                               qparm.SqlDbType InsUpSel(1ic)
 
                               qparm.SourceColumn InsUpSel(0ic)
 
                               Command.Parameters.Add(qparm)

 
                           End If

 
                       End If

 
                   ElseIf InsUpSel(3ic) = "prim" And Not (Command.Parameters.Contains(OrginalKey)) Then
                        CurrentKey 
""
 
                       OrginalKey ""
 
                       CurrentKey InsUpSel(0ic)
 
                       OrginalKey InsUpSel(2ic)
 
                       qparm.ParameterName InsUpSel(2ic)
 
                       qparm.SqlDbType InsUpSel(1ic)
 
                       Command.Parameters.Add(qparm)
 
                       ''''''''''
 
                       If Not (Command.Parameters.Contains("@Orginal_" CurrentKey)) Then

                            qparm 
= New SqlParameter
                            qparm
.ParameterName "@Orginal_" CurrentKey
                            qparm
.SqlDbType InsUpSel(1ic)
 
                           qparm.SourceColumn InsUpSel(0ic)
 
                           qparm.SourceVersion DataRowVersion.Original
                            qparm
.Direction ParameterDirection.Output
                            Command
.Parameters.Add(qparm)
 
                       End If
 
                   End If
 
               Next
                qf 
+= 1
            Next

            Updatest 
"Update " _TableName " Set " qfiled "  Where " CurrentKey " = " OrginalKey
            
' MsgBox(Updatest)


        End If
        Command.CommandText = Updatest

        Return Command
    End Function 

الادخال INSERT 
لا شيئ جديد حددنا الحقول كما سابقه و قمنا فقط باستثناء البارميتر الخاص بالمفتاح الرئيسي اذا كان الحقل الذي تتعامل معه من النوع ترقيم تلقائي او قم باضافته اذا كنت تستخدم حقل خاص بك لكن تذكر ان تفحص قيمة الحقل قبل الارسال لكي لا تنشئ لديك قيم مكررة
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بانشاء جملة ادخال للكوماند المحدد
    
''' يتم استخدام اسم الجدول المحدد
    ''' 
يتم من خلاله انشاء بارميترات للكوماند المحدد
    
''' توافق اسماء الحقول في الجدول
    ''' 
</summary>
 
   ''' <param name="Command">مرر اسم الكوماند فقط</param>
    ''' 
<param name="Columns">مرر مصفوفة نصية تحتوي على اسماء الحقول بامكانك استخدام علامة للاشارة الى كل الحقول</param>
 
   ''' <returns>يعيد كائن كوماند يحمل جملة الادخال</returns>
    ''' 
<remarks>
 
   ''' ان اي خطأ في اسماء الحقول لن يعمل الاجراء بشكل صحيح
    ''' 
<example>
 
   ''' <code>
    ''' 
Dim Cols() As String = {"name","phone"}
 
   ''' </code>
    ''' 
</example>
 
   ''' </remarks>
    Private Function Create_Insert_For_Command8(ByVal Command As SqlCommand, ByVal ParamArray Columns() As String) As SqlCommand
        If _TableName = "" Or _TableName Is Nothing Then
            MsgBox("حدد اسم الجدول اولا", , "from Create_Insert_For_Command ")
            Return Nothing
            Exit Function
        End If
        '
-----------------------------------------------------------------
 
       Command Command
        Command
.Connection GetSqlConnection
        Command
.Parameters.Clear()
 
       '=============================================================
        Dim insertall As String = ""
        Dim select1 As String = "Select "
        Dim qfiled As String = ""
        Dim qvalue As String = ""
        Dim qf As Integer = 0
        Dim qparm As New SqlParameter
        If Columns(0) = "*" Then

            For ic = 0 To InsUpSel.GetLength(1) - 1
                qparm = New SqlParameter
                If Not (InsUpSel(3, ic) = "prim") Then
                    If qf = InsUpSel.GetLength(1) - 1 Then
                        qfiled += InsUpSel(0, ic)
                        qvalue += InsUpSel(2, ic)
                        qparm.ParameterName = InsUpSel(2, ic)
                        qparm.SqlDbType = InsUpSel(1, ic)
                        qparm.SourceColumn = InsUpSel(0, ic)
                        Command.Parameters.Add(qparm)
                    Else
                        qfiled += InsUpSel(0, ic) & ","
                        qvalue += InsUpSel(2, ic) & ","
                        qparm.ParameterName = InsUpSel(2, ic)
                        qparm.SqlDbType = InsUpSel(1, ic)
                        qparm.SourceColumn = InsUpSel(0, ic)
                        Command.Parameters.Add(qparm)

                    End If

                End If

                qf += 1
            Next



            If InsUpSel(3, 0) = "prim" Then
                Dim keyorginal As String
                keyorginal = InsUpSel(0, 0)
                select1 += keyorginal & "," & qfiled & " from " & _TableName & " Where " & keyorginal & " = " & " SCOPE_IDENTITY()"
            Else
                select1 += qfiled & " from " & _TableName
            End If

            insertall = "INSERT INTO " & _TableName & vbCrLf & " (" & qfiled & ")" & vbCrLf & "Values " & vbCrLf & "(" & qvalue & ")" & vbCrLf & select1

            Command.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord
            qfiled = ""
            qf = 0

        ElseIf Columns(0) <> "*" And Columns.Length >= 1 Then
            Columns = Columns
            If checkfileds(Columns) = True Then
                Return Nothing
                Exit Function
            End If


            For Each Str As String In Columns
                For ic = 0 To InsUpSel.GetLength(1) - 1
                    If Not (InsUpSel(3, ic) = "prim") Then
                        If Str = InsUpSel(0, ic) Then
                            qparm = New SqlParameter
                            If qf = Columns.Length - 1 Then
                                qfiled += InsUpSel(0, ic)
                                qvalue += InsUpSel(2, ic)
                                qparm.ParameterName = InsUpSel(2, ic)
                                qparm.SqlDbType = InsUpSel(1, ic)
                                qparm.SourceColumn = InsUpSel(0, ic)
                                Command.Parameters.Add(qparm)
                                ' 
Exit For
 
                           Else
                                qfiled 
+= InsUpSel(0ic) & ","
 
                               qvalue += InsUpSel(2ic) & ","
 
                               qparm.ParameterName InsUpSel(2ic)
 
                               qparm.SqlDbType InsUpSel(1ic)
 
                               qparm.SourceColumn InsUpSel(0ic)
 
                               Command.Parameters.Add(qparm)

 
                           End If
 
                       Else

                        End 
If
 
                   End If



 
               Next
                qf 
+= 1
            Next
            insertall 
"INSERT INTO " _TableName vbCrLf " (" qfiled ")" vbCrLf "Values " vbCrLf "(" qvalue ")"


 
       End If



 
       Command.CommandText insertall
        Return Command

    End 
Function 

عملية الحذف DELETE
الحذف يجري بطريقة معتادة وفق قيمة المفتاح الرئيسي و هو معروف لديكم جميعا
كما انني اردت ان اعمل طريقة اخرى لحذف كل محتويات الجدول
الحذف وفق معيار محدد
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بانشاء جملة استعلام لعملية حذف صف محدد
    
''' وفق قيمة المفتاح الرئيسي
    ''' 
</summary>
 
   ''' <param name="Command">كائن الكوماند</param>
    ''' 
<returns>يعود بكائن الكوماند المرسل</returns>
 
   ''' <remarks></remarks>
    Private Function Create_Delete_For_Command(ByVal Command As SqlCommand) As SqlCommand
        If _TableName = "" Or _TableName Is Nothing Then
            MsgBox("حدد اسم الجدول اولا", , "From Create_Delete_For_Command ")
            Return Nothing
            Exit Function
        End If
        '
-----------------------------------------------------------------------
 
       Command Command
        Command
.Connection GetSqlConnection
        Command
.Parameters.Clear()

 
       Dim Deletest As String "Delete From " _TableName " Where "
 
       Dim parm As New SqlParameter
        
'

        Dim OrginalKye As String = ""
        For ic = 0 To InsUpSel.GetLength(1) - 1
            If InsUpSel(3, ic) = "prim" Then
                OrginalKye = InsUpSel(0, ic)
                parm.ParameterName = InsUpSel(2, ic)
                parm.SqlDbType = InsUpSel(1, ic)
                parm.SourceColumn = InsUpSel(0, ic)
                parm.SourceVersion = DataRowVersion.Original
                Command.Parameters.Add(parm)

            End If
        Next
        Deletest += "(" & OrginalKye & "=" & "@" & OrginalKye & ")"

        '

 
       Command.CommandText Deletest
        Return Command
    End 
Function 

حذف كامل الصفوف في الجدول المحدد
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بانشاء جملة استعلام لعملية حذف
    
''' كل الصفوف في الجدول المحدد
    ''' 
</summary>
 
   ''' <param name="Command">كائن كوماند</param>
    ''' 
<returns>يعود بكائن الكوماند المرسل</returns>
 
   ''' <remarks></remarks>
    Private Function Create_DeleteAll_For_Command(ByVal Command As SqlCommand) As SqlCommand
        If _TableName = "" Or _TableName Is Nothing Then
            MsgBox("From Create_DeleteAll_For_Command " & "حدد اسم الجدول اولا")
            Return Nothing
            Exit Function
        End If

        '
-----------------------------------------------------------------------
 
       Command Command
        Command
.Connection GetSqlConnection
        
'--------------------------------------------------------------------------
        Dim Deletest As String = "Delete  From " & _TableName

        Command.CommandText = Deletest
        Return Command
    End Function 

ماذا بعد ذلك 
احببت ان اضمن كل عملنا السابق و اضافة كل كائنات SQL COMMANDS الى كائن SQL DATA ADAPTER
ليتكفل هو بالعملية كاملة يمكنك تخطيها اذا احببت
PHP كود :
   ''' <summary>
    ''' 
اجراء يقوم بتمهيد كائن الادبتر وفق الجدول المحدد
    
''' و يقوم بتجهيز كائنات الكوماند المناسبة مع البارمترات اللازمة
    ''' 
</summary>
 
   ''' <param name="Columns"> * مصفوفة الحقول يمكنك استخدام علامة  </param>
    ''' 
<returns>يعيد كائن ادبتر </returns>
 
   ''' <remarks></remarks>
    Public Function Creat_Adapter(ByVal ParamArray Columns() As String) As SqlDataAdapter

        Dim table1 As String = TableName
        LoadTxtFiled()
        '
----------------
 
       Me._adapter = New SqlClient.SqlDataAdapter()
 
       Dim tableMapping As DataTableMapping = New DataTableMapping()
 
       tableMapping.SourceTable table1 ' "Table"
        tableMapping.DataSetTable = table1 '"class"
 
       '------------------------------------------------------------------
        If Dt.Columns.Count > 0 Then
            For Each dc As DataColumn In Dt.Columns
                tableMapping.ColumnMappings.Add(dc.ColumnName, dc.ColumnName)
            Next
            Me._adapter.TableMappings.Add(tableMapping)
        End If
        '
---------------------------------------------------------------------------
 
       Dim SelCommand As New SqlClient.SqlCommand
        Dim UpCommand 
As New SqlClient.SqlCommand
        Dim InsCommand 
As New SqlClient.SqlCommand
        Dim DelCommand 
As New SqlClient.SqlCommand
        
'--------------------
        SelCommand = Me.Create_Select_For_Command(SelCommand, Columns)
        '
-------------------
 
       UpCommand Me.Create_update_For_Command(UpCommandColumns)
 
       '-------------------
        InsCommand = Me.Create_Insert_For_Command8(InsCommand, Columns)
        '
-----------------
 
       DelCommand Me.Create_Delete_For_Command(DelCommand)
 
       '----------------------
        Me._adapter.SelectCommand = SelCommand
        Me._adapter.InsertCommand = InsCommand
        Me._adapter.UpdateCommand = UpCommand
        Me._adapter.DeleteCommand = DelCommand
        Me._adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
        Return Me._adapter
    End Function 

(25-06-16, 04:29 AM)khodor1985 كتب : بتصور فينا نكتب الكلاس بطريقة أسهل من هيك، هيدا رأيي طبعا.
مشكور على جهودك

مشكور اخي خضر على المشاركة اكيد فيك تكتبه بطرق سهلة اكثر و حسب مزاجك
الموضوع برمته كان على عجالة و الكلاس سيتم تجريبه اكثر للتاكد من عمله
و يمكن الاستفادة من الالية لتطويرها بما يتناسب مع تصورك للهدف

بعد ذلك لم يتبقى لدينا الى عملية تخريج الكلاس BUILD لنحصل على ملف Dll نستخدمه في مشروعنا
ساقوم بوضع تجريب بسيط للتعامل مع الكلاس لاحقا


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16

كلام جميل اخي خضر و هذه الهندسة هي اللبنة الاساسية في بناء برامج كبيرة
نحن نستخدم هذه التقنية لبناء البرامج التجارية في اغلب الاحيان
انا عن نفسي لا احب استخدام اي جزء يختص بالتعامل مع البيانات في واجهة البرنامج , كله يكون في قاعدة البيانات
اما من ناحية البرنامج فلا احتاج الا بناء الكلاسات الخاصة للتخاطب مع القاعدة و من ثم واجهة المستخدم التي تتخاطب مع الكلاسات السابقة
هكذا تكون قد فصلت كل شيئ لوحده
يوجد من الكلام الكثير الكثير عن هذه التقنية ربما في قادم الايام ان شاء الله ستكون لي وقفة مفصلة و يا ريت بالتعاون مع شخصكم و باقي الاعضاء للخروج بمرجع جيد عنها
تحياتي لك

بسم الله الرحمن الرحيم
استكمالا لما سبق ساضع مثال تجريب على الكلاس الذي انشأناه سابقا للتجريب
اولا سانشئ قاعدة بيانات بسيطة على السيرفر مؤلفة من 3 جداول
جدول الزبائن

جدول الطلبيات او الفواتير


جدول تفاصيل الفاتورة او المواد

و ساضع السكربت الخاص بها اسفل الموضوع
اردت استخدام الكلاس السابق مباشرة في عملية التحديث على القاعدة , على كل الجداول السابقة
و ساعمل نموذج في واجهة اللغة كما يلي

سنستورد الكلاس السابق الذي اصبح مكتبة الى مراجعنا و نتعامل معه كما ساعرف بعض الكائنات للتعامل الجداول السابقة كما يلي

PHP كود :
Imports System.Data.SqlClient
Imports SQLDBConnect

Public Class Clients
    Dim da1
da2da3 As SqlClient.SqlDataAdapter
    Dim ds 
As New DataSet
    Dim d1
d2d3 As New DbConect 

انا عدلت على الكلاس السابق في جزئية جلب السيرفرات فقط حيث لم تعمل معي في الوندوز 10 مع انها مازالت تعمل في وندوز 7
على اي حال انا ساضع الكلاس مرفق مع المثال


الكود التالي في حدث تحميل النموذج و هو مشروح بالكامل

PHP كود :
   Private Sub Clients_Load(sender As ObjectAs EventArgsHandles MyBase.Load
        
'تعين الاتصال الى القاعدة
        DbConect.SetConnectionString_ForDb("ClientDb")
        '
فتح الاتصال
        DbConect
.OpenSqlConnection()
 
       'تحديد اسماء الجداول التي نريد التعامل معها
        d1.TableName = "ClientsTb"
        d2.TableName = "OrdersTb"
        d3.TableName = "GoodsTb"
        '
هنا انا اخترن جميع الحقول
        Dim fild
() As String = {"*"}
 
       'تفريغ الداتاسيت
        ds.Clear()
        '
----------------------------------
 
       'Adapter انشاء كائنات
        '
و ربطها مع الجداول السابقة
        da1 
= New SqlClient.SqlDataAdapter
        da1 
d1.Creat_Adapter(fild)
 
       '------------
        da2 = New SqlClient.SqlDataAdapter
        da2 = d2.Creat_Adapter(fild)
        '
------------------------
 
       da3 = New SqlClient.SqlDataAdapter
        da3 
d3.Creat_Adapter(fild)
 
       'ملئ الداتاسيت ببيانات الجداول
        da1.Fill(ds, d1.TableName)
        da2.Fill(ds, d2.TableName)
        da3.Fill(ds, d3.TableName)
        ds.AcceptChanges()

        '
انشاء علاقات بين الجداول
        
'----------------------------.زبائن و طلبيات-------------------------------------
        Dim col1 As DataColumn = ds.Tables(d1.TableName).Columns("Cl_Id") '
جدول الزبائن
        Dim col2 
As DataColumn ds.Tables(d2.TableName).Columns("Cl_Id"'جدول الطلبيات
        Dim re As New DataRelation("Clt_Ord", col1, col2)
        ds.Relations.Add(re)
        ''----------------------------طلبيات و مواد---------------------------------------
        Dim col4 As DataColumn = ds.Tables(d2.TableName).Columns("Ord_Id") '
جدول الطلبيات
        Dim col5 
As DataColumn ds.Tables(d3.TableName).Columns("Ord_Id"'جدول المواد
        Dim re3 As New DataRelation("Ord_Gods", col4, col5)
        ds.Relations.Add(re3)
        '
BindingSource ربط كائنات
        
'بمصدر بيانات
        bn1.DataSource = ds.Tables(d1.TableName)
        bn2.DataSource = bn1
        bn2.DataMember = "Clt_Ord"
        bn3.DataSource = bn2
        bn3.DataMember = "Ord_Gods"
        '
DataGrids و كذلك ربط
        Dg1
.DataSource bn1
        dg2
.DataSource bn2
        dg3
.DataSource bn3
        
'اغلاق الاتصال
        DbConect.CloseSqlConnection()
        '
عرض اسم السيرفر و حالة الاتصال و جملة الاتصال اسفل النموذج
        ST1
.Items(0).Text DbConect.GetSQlConnectionString " | "
 
       ST1.Items(2).Text DbConect.GetSrvName
        ST1
.Items(1).Text DbConect.GetConnectionState " | "

 
   End Sub 

و الكود التالي في زر الحفظ

PHP كود :
   'اجراء الحفظ
    Private Sub SaveBtn_Click(sender As Object, e As EventArgs) Handles SaveBtn.Click
        Me.Validate()
        bn1.EndEdit()
        bn2.EndEdit()
        bn3.EndEdit()

        Dim SaveDataSet As New DataSet
        SaveDataSet = ds.Clone

        If ds.HasChanges = True Then
            SaveDataSet = ds.GetChanges(DataRowState.Added Or DataRowState.Deleted Or DataRowState.Modified)

            If (Not (SaveDataSet) Is Nothing) Then

                '
*******هذه الاحداث لعرض العمليات و لا دخل لها بعملية الحفظ قم بازالتها
                AddHandler da3
.RowUpdatingAddressOf OnRowUpdating
                AddHandler da3
.RowUpdatedAddressOf OnRowUpdated
                
'*******

                da1.Update(SaveDataSet, d1.TableName)
                da2.Update(SaveDataSet, d2.TableName)
                da3.Update(SaveDataSet, d3.TableName)

                '
********
 
               RemoveHandler da3.RowUpdatingAddressOf OnRowUpdating
                RemoveHandler da3
.RowUpdatedAddressOf OnRowUpdated
                
'********

                ds.Merge(SaveDataSet)
                ds.AcceptChanges()
            End If

        End If

    End Sub 

فقط هذا كل ما احتجناه لعمليات الحفظ مهما كانت العمليات التي تمت على الجداول
انا اضفت حدثين اضافيين لتعرف ما الذي حصل اثناء عملية الحفظ و تحديدا لجدول تفاصيل الفاتورة فقط

PHP كود :
   Private Sub OnRowUpdating(sender As ObjectAs SqlRowUpdatingEventArgs)
 
       PrintEventArgs(e)
 
   End Sub

    Private Sub OnRowUpdated
(sender As ObjectAs SqlRowUpdatedEventArgs)
 
       PrintEventArgs(e)
 
   End Sub

    Private Overloads Sub PrintEventArgs
(args As SqlRowUpdatingEventArgs)

 
       TextBox1.Text += Environment.NewLine & ("OnRowUpdating")
 
       TextBox1.Text += Environment.NewLine & ("  event args: (" " command=" args.Command.CommandText &
 
            " commandType=" args.StatementType " status=" args.Status ")")
 
   End Sub


    Private Overloads Sub PrintEventArgs
(args As SqlRowUpdatedEventArgs)
 
       TextBox1.Text += Environment.NewLine & ("OnRowUpdated")
 
       TextBox1.Text += Environment.NewLine & ("  event args: (" " command=" args.Command.CommandText &
 
          " commandType=" args.StatementType " recordsAffected=" &
 
          args.RecordsAffected " status=" args.Status ")")
 
   End Sub 

و هذا تجريب من واجهة الادخال


و اخيرا المثال مرفق مع سكربت القاعدة لمن يحب ان يجرب

الجزئية التي تم تعديلها في الكلاس السابق 

PHP كود :
   Private Shared Sub GetServerList()
 
       Dim Server As String String.Empty
 
       Dim instance As Sql.SqlDataSourceEnumerator Sql.SqlDataSourceEnumerator.Instance
        Dim table 
As System.Data.DataTable instance.GetDataSources()
 
       Dim Machine As String String.Empty

 
       For p As Integer 0 To table.Rows.Count 1
            Server 
String.Empty
 
           Server table.Rows(p).Item("ServerName")
 
           If table.Rows(p).Item("ServerName").ToString.Length 0 Then
                If table
.Rows(p).Item("ServerName") = Machine Then
                    Machine 
= (System.Environment.MachineName)
 
                   Server table.Rows(p).Item("ServerName")
 
                   ReDim SrvNameArray(table.Rows.Count 1)
 
                   SrvNameArray.SetValue(Serverp)
 
               Else
                    Machine 
= (System.Environment.MachineName "\" + table.Rows(p).Item("ServerName"))
                    ReDim SrvNameArray(table.Rows.Count - 1)
                    SrvNameArray.SetValue(Server, p)
                End If
                MsgBox(SrvNameArray.Count)
            End If
        Next



    End Sub 



RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - الوادي - 26-06-16

يا ابو ليلى،

أنا اسمي مكتوب؟ طييييييييب.



مجهود رائع ومرتب


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16

ايوا مكتوب يا غالي
 عبد البصير الملقب بالوادي Big Grin  


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 26-06-16

بارك الله بك اخي خضر و بكل الاخوة الموجودين


RE: صمم الكلاس الخاص بك - كلاس للتعامل مع SQL SERVER - ابو ليلى - 28-06-16

السلام عليكم و رحمة الله و بركاته
كنت في هذا الكلاس قد اشرت الى نقطة تخص الكلاس ServSite 

و كانت الافضلية لفصل اجراءات السيرفر عن الاجراءات الخاصة بالقاعدة و اجلت الحديث عنها الى حين اكتمال الفكرة لدي
و الفكرة هي انشاء مدير للسيرفر كما هي الحال مع SQL Server Management Studio 
و الاستفادة من الكلاس السابق الى اقصى الحدود و تطويره حسب اي اتجاه ترغب فيه
يمكنك التوسع في اي اتجاه تحبه و تفضله كأن تصبح قادراً على انشاء قواعد البيانات و كائناتها المختلفة من خلال الكود او ابتداع المعالج الخاص بك ....الخ
انا احببت التوسع في اتجاهين الى الان 
الاتجاه الاول:عرض كل كائنات السيرفر لدي بكل ما تحتويه من قواعد و من جداول و استعلامات و اجراءات و مستخدمين و مجموعات.
الاتجاه الثاني:هو صناعة مدير خاص بالاجراءات المخزنه Stored Procedure , مهمته اعطائك وسيلة ذكية و سريعة لانشاء اي نوع من الاجراءات المعتادة 
الاضافة و الحذف و التعديل و الحفظ و استعلامات التحديد بكل اشكالها البسيطة و المعقدة مع فرض كل انواع البارمترات التي توافق الحقول و الكثير الكثير و مازال التوسيع جاريا للخروج بافضل شكل و اسهل استخدام.
الفكرة المستقبلية :هي استغلال كل ما يقدمه SQL Server من امكانية و استغلالها خلال عملنا و خصوصا باب الصلاحيات و الاذونات الخاصة بكل قاعدة و جدول و حقل و فرضها داخل عملنا 
لا ادري صراحة ان كنت ساخرج بنتيجة من دراسة هذه الجزئية (الصلاحيات و الاذونات من  SQl Server  الى داخل اطار العمل) لم اتوفر على مصادر في هذا الاتجاه 
ما الغاية من كل هذا العمل ؟؟؟؟ لماذا تعيد اختراع العجلة.
ليس لشيئ كما احب ان اقول دائما لغاية في نفس يعقوب.
اترككم مع الصور الاولية من الاتجاهات التي تحدثت عنها سابقا تم انجازها و الحمد لله تعمل بكفائة عالية , لكن واجهتني مشكلة تبسيط الواجهة لجعلها سهلة الاستخدام