تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
Collection & DataBase Part 2
#1
السلام عليكم ورحمة الله وبركاته



مقدمــــة:


الهدف من الموضوع هو بناء Collection تدعم الداتا بيز

في الجزء الأول  Collection & DataBase Part 1   تم توضيح كيفية بناء  Collection من الصفر لكن وبما أن الدوت نت به الكثير من Collection وبها صفات أفضل كثيرا مما كتبناه سابقا في الجزء الأول لذلك ومن الأفضل أن نستخدم بعضا من Collections المتاحة لنا في الدوت نت و بالتالي هذا سيوفر علينا الكثير من الجهد والوقت

في أي برامج داتا بيز نحتاج الي تخزين بيانات بأشكال مختلفة علي سبيل المثال نحتاج الي تخزين بيانات اسعار او معاملات تجارية او بيانات شخصية او بيانات عامة او بيانات خاصة بالشركات و المؤسسات و الأفراد عموما مهما كان شكل المدخلات التي نريد الاحتفاظ بها و تخزينها فإن الاسلوب المستخدم سيظل واحدا مهما اختلفت التقنية المستخدمة في تخزين البيانات

وبدلا من الجديث النظري ولتوضيح الأمر قليلا سنعطي مثالا توضيحيا

مثال:

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

لذلك نحن نحتاج الي كلاس سيكون الهدف منه إدخال البياات الي الداتا بيز و هذا الكلاس سوف نطلق عليه الإسم  Person

وبما ان الشركة ليس بها موظفا واحدا وربما عدد موظفيها قد يتعدي المئات أو الالاف من الأشخاص لذلك نحن هنا نحتاج إلي Collection نخزن بها البيانات الخاصة بكل شخص اأو نخزن بها المدخلات و لسوف نطلق علي هذه Collection الإسم PersonCollection

الكلاس Person

هذا الكلاس مثله مثل اي كلاس سيكون له Constructor و سيكون به بعض Property تعبر عن المدخلات الخاصة بكل شخص لكن يتبقي بعض الاسئلة الهامة جدا وهي كالتالي و يجب ان نضع في الاعتبار ان الاجابة علي هذه الاسئلة سيؤثر علي شكل الكود الخاص بالكلاس :

1- هل نريد الاحتفاظ بصورة لكل موظف؟ إن كانت الإجابة نعم إذن هذا الكلاس يجب أن يدعم  IDisposable Interface

2- كيف يتم التفريق بين المدخلات الخاصة بكل بالموظفين ؟ في الداتا بيز التقليدية مثل SQL سنجد ان أي ملف نقوم ببنائه يكون به مفتاح خاص وهذا المفتاح يتم استخدامه لإعطاء رقم متفرد لكل موظف وغالبا هذا المفتاح الهدف منه هو تسهيل عمليات البحث و الفلترة للموظفين

وبشكل مبدئي الكلاس Person سيكون به مدخلات بسيطة مثل إسم الشخص و المفتاح الخاص بهذا الشخص و رقم التليفون و صورة لهذا الشخص و لاحقا وكلما تقدمنا في الموضوعات التي تناقش نفس فكرة المقال سوف نضيف للكلاس بيانات اخري.

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

الخياران متاحان و الأمر بالنهاية متروك للمبرمج

عموما الفكرة المستخدمة في كيفية صناعة مفتاح متفرد لكل شخص يتم إدخال بياناته يمكن تطويرها و استخدامها لتوليد  SerialNo لحماية البرنامج.

الدوال التالية توضح كيفية توليد رقم يمكن استخدامه كنوع من المفتاح للتعريف عن كل شخص

و علي فكرة انا لم أخترع شيئاجديدا فقط أنا قرأت الأمثلة الموجودة في مواقع مايكروسوفت و اخذت منها و قمت ببناء الدوال بما يتناسب مع احتياجات الموضوع الذي نتحدث عنه و الدول يمكن كتابتها في كلاس منفصل او يمكن اضافتها للكلاس Person و الأمر متروك للمبرمج
يجب إضافة فضاء الاسماء System.Numerics لكي تعمل الدول بدو أخطاء


PHP كود :
  Friend Function GenerateKeyLINQ(value As String) As String

        Dim textValue 
As String value
        Dim keyValue 
As String CType(NothingString)
 
       If Not String.IsNullOrEmpty(textValueThen

            Dim query 
As IEnumerable(Of Char) = From c As Char In textValue Where (Not Char.IsWhiteSpace(cAndAlso Char.IsLetter(c)) Select c
            Dim number 
As BigInteger 1
            For Each c 
As Char In query
                Dim i 
As BigInteger = New BigInteger((Encoding.ASCII.GetBytes(c.ToString)))
 
               number *= i
            Next

            number 
*= value.Length

            
' if longer number required uncomment the below line of code
            '
number Math.Pow(number2)
 
           number BigInteger.Abs(number)

 
           Dim bytes As List(Of Byte) = New List(Of Byte)
 
           For Each c As Char In number.ToString
                bytes
.Add(Convert.ToByte(c))
 
           Next
            Dim nString 
As String Convert.ToBase64String(bytes.ToArray)
 
           nString nString.Replace("=""")
 
           nString nString.Replace("+""")

 
           keyValue number.ToString " - " nString.ToUpper
        End 
If
 
       Return keyValue
    End 
Function

 
   Friend Function GenerateKey(value As String) As String
        Dim textValue 
As String value
        Dim keyValue 
As String CType(NothingString)
 
       If Not String.IsNullOrEmpty(textValueThen
            Dim number 
As BigInteger 1
            For i 
As Integer 0 To textValue.Length 1
                Dim c 
As Char textValue(i)
 
               If Not Char.IsWhiteSpace(cAndAlso Char.IsLetter(cThen
                    Dim j 
As BigInteger = New BigInteger((Encoding.ASCII.GetBytes(c.ToString)))
 
                   number *= j
                End 
If
 
           Next

            number 
*= value.Length

            
' if longer number required uncomment the below line of code
            '
number Math.Pow(number2)
 
           number BigInteger.Abs(number)

 
           Dim bytes As List(Of Byte) = New List(Of Byte)
 
           For Each c As Char In number.ToString
                bytes
.Add(Convert.ToByte(c))
 
           Next

            Dim nString 
As String Convert.ToBase64String(bytes.ToArray)
 
           nString nString.Replace("=""")
 
           nString nString.Replace("+""")

 
           keyValue number.ToString " - " nString.ToUpper
        End 
If
 
       Return keyValue
    End 
Function 

عموما الدالتان أعلاه تؤديان نفس الغرض و عليك فقط ان تستخدم احدهما
أيضا وفي المرفقات ستجدون مثالا لكيفية استخدام هذا الدوال في توليد ارقام يمكن استخادمها لحماية برامجنا

كودالكلاس Person

PHP كود :
Imports System.Numerics
Imports System
.Text

Public Class Person
    Implements IDisposable

    Private _key 
As String CType(NothingString)
 
   Private _img As Image CType(NothingImage)
 
   Private _disposed As Boolean

    Public Sub 
New(name As Stringimg As ImagecellNo As String)
 
       If String.IsNullOrEmpty(nameThen
            Throw 
New ArgumentException("Please specify the person name""name")
 
       End If
 
       Me.Name name
        Me
._key Me.GenerateKeyLINQ(Me.Name)
 
       Me.Image img
        Me
.CellNo cellNo
    End Sub

    Public Property Name 
As String
    Public Property CellNo 
As String

    Public Property Image 
As Image
        Get
            Return Me
._img
        End Get
        Set
(value As Image)
 
           If Me._img IsNot value Then
                Me
._img value
            End 
If
 
       End Set
    End Property

    Protected ReadOnly Property Key 
As String
        Get
            Return Me
._key
        End Get
    End Property

    
' for Test purpose only
    Friend ReadOnly Property ID As String
        Get
            Return Me._key
        End Get
    End Property

    Friend Function GenerateKeyLINQ(value As String) As String

        Dim textValue As String = value
        Dim keyValue As String = CType(Nothing, String)
        If Not String.IsNullOrEmpty(textValue) Then

            Dim query As IEnumerable(Of Char) = From c As Char In textValue Where (Not Char.IsWhiteSpace(c) AndAlso Char.IsLetter(c)) Select c
            Dim number As BigInteger = 1
            For Each c As Char In query
                Dim i As BigInteger = New BigInteger((Encoding.ASCII.GetBytes(c.ToString)))
                number *= i
            Next

            number *= value.Length

            ' 
if longer number required uncomment the below line of code
            
'number = Math.Pow(number, 2)
            number = BigInteger.Abs(number)

            Dim bytes As List(Of Byte) = New List(Of Byte)
            For Each c As Char In number.ToString
                bytes.Add(Convert.ToByte(c))
            Next
            Dim nString As String = Convert.ToBase64String(bytes.ToArray)
            nString = nString.Replace("=", "")
            nString = nString.Replace("+", "")

            keyValue = number.ToString & " - " & nString.ToUpper
        End If
        Return keyValue
    End Function

    Protected Sub OnDispose()
        If Me._img IsNot Nothing Then
            Me._img.Dispose()
            Me._img = Nothing
        End If
    End Sub

    Protected Overridable Sub Dispose(disposing As Boolean)
        If Me._disposed Then
            Return
        End If

        If disposing Then
            Me.OnDispose()
        End If
        Me._disposed = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

End Class 


كيف نستخدم الأكواد أعلاه مع الفورم و الكونترول الموجودة علي الفورم وذلك بدون بناء Collection  من الصفر

اولا : داخل الفورم نقوم بتعريف متغير يعبر عن اي Collection أو Generic List الموجودة بكثرة في الدوت نت و هنا سوف استخدم Generic List


PHP كود :
Private persons As New List(Of Person

لكن قبل ان نفعل اي شئ بالكود نحن هنا نحتاج الي ايجاد شخص ما داخل Generic List لذلك نحن نحتاج الي أن نكتب بعض الدوال التي سوف تساعدنا علي ايجاد أي شخص موجود في Generic List

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

PHP كود :
 ' You may use LINQ to find the person by his name
    Friend Function FindPerson(name As String) As Person
        Dim result As Person = CType(Nothing, Person)
        If Not (String.IsNullOrEmpty(name)) Then
            For Each p As Person In Me.persons
                If p.Name.ToLowerInvariant() = name.ToLowerInvariant() Then
                    result = p
                    Exit For
                End If
            Next
        End If
        Return result
    End Function

    Friend Function FindPersonLINQ(name As String) As Person
        Dim result As Person = CType(Nothing, Person)
        Dim query As IEnumerable(Of Person) = CType(Nothing, IEnumerable(Of Person))
        If Not (String.IsNullOrEmpty(name)) Then
            query = From anyPerson As Person In persons Where anyPerson.Name.ToLowerInvariant() = name.ToLowerInvariant() Select anyPerson
        End If

        For Each item As Person In query
            result = New Person(item.Name, item.Image, item.CellNo)
        Next
        Return result
    End Function

    Friend Function FindPersonKey(name As String) As String
        Return FindPerson(name).ID
    End Function

    Friend Function FindStudentPhone(name As String) As String
        Return FindPerson(name).CellNo
    End Function 

ثانيا: نقوم بإضافة بعض الاشخاص الي Generic List و ذلك في الحدث Load الخاص ب الفورم


PHP كود :
       Dim p1 As Person = New Person("Ahmed Reda"Nothing"01099999999")
 
       Dim p2 As Person = New Person("Ahmed ali"Nothing"01088888888")
 
       Dim p3 As Person = New Person("Ahmed Mahmoud"Nothing"01077777777")
 
       Dim p4 As Person = New Person("Ahmed Alaa"Nothing"01066666666")
 
       Dim p5 As Person = New Person("Ahmed Mostafa"Nothing"01055555555")
 
       Dim p6 As Person = New Person("Ahmed Omar"Nothing"01044444444"


ثالثا: نعرض البيانات في اي كونترول مثل ListBox

PHP كود :
  For Each p As Person In persons
            ListBox1
.Items.Add(p.Name)
 
       Next 

الان كيف نربط البيانات مع الداتا جريد فيو

يمكننا ان نستخدم اي اسلوب نراه مناسباأو من الأفضل و الاسهل لنا هو أن نقوم بتحويل البيانات الموجودة في Generic List الي Data Table لتكون بمثابة Data Source  للداتا جريد فيو

كيف نقوم بتحويل Generic List التي تم تعريفها اعلاه في الكود الي Data table
الكود التالي يوضح كيف نفعل ذلك

PHP كود :
Friend Function PersonsToDataTable() As DataTable
        Dim result 
As DataTable CType(NothingDataTable)
 
       result = New DataTable With {.Locale System.Globalization.CultureInfo.InvariantCulture}
 
       result.Columns.Add(New DataColumn("Key"GetType(String)))
 
       result.Columns.Add(New DataColumn("Name"GetType(String)))
 
       result.Columns.Add(New DataColumn("Phone"GetType(String)))
 
       result.Columns.Add(New DataColumn("Image"GetType(Image)))
 
       SyncLock Me.persons.GetType
            For i 
As Integer 0 To Me.persons.Count 1
                result
.Rows.Add(New Object() {Me.persons(i).IDMe.persons(i).NameMe.persons(i).CellNoMe.persons(i).Image})
 
           Next
            Return result
        End SyncLock
    End 
Function 

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

قد يتساءل البعض أليس من الأسهل استخدام LINQ to SQL or LINQ to XML
بالطبع نعم أسهل ويمكن عمل ذلك بكل بساطة
لكن بعض الفئات من المبرمجين يفضلون بناء كل شئ ب أنفسهم و مايكروسوفت تركت جميع الخيارت متاحة طبقا لرؤية كل مبرمج

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

مع تحياتي بالتوفيق للجميع


الملفات المرفقة
.rar   Test_KeyGenerator_Vb4Arab.rar (الحجم : 71.54 ك ب / التحميلات : 50)
.rar   Test_Prson_Vb4Arab.rar (الحجم : 79.24 ك ب / التحميلات : 44)
الرد }}}
تم الشكر بواسطة: HASAN6.0 , Sajad , محمد كريّم , viv


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  Generic Delegates & ًWindows Forms Control - Part 2 silverlight 0 2,525 19-01-16, 02:01 PM
آخر رد: silverlight
  Generic Delegates & ًWindows Forms Control - Part 1 silverlight 1 2,667 16-01-16, 06:35 PM
آخر رد: 10468
  [مقال] Notify Collection Changed silverlight 3 2,411 02-11-15, 06:07 PM
آخر رد: الشاكي لله
  Collection & DataBase Part 1 silverlight 1 2,572 25-07-15, 07:55 AM
آخر رد: silverlight
  save rtf file in database محمد عمر مصطفى 0 2,418 21-12-13, 02:50 AM
آخر رد: محمد عمر مصطفى

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


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