التنبيهات التالية ظهرت :
Warning [2] count(): Parameter must be an array or an object that implements Countable - Line: 864 - File: showthread.php PHP 7.4.33 (Linux)
File Line Function
/showthread.php 864 errorHandler->error



تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
[VB.NET] تطبيق على طرق LINQ - صانع اكواد SQL صغير mini SQL generator
#1
بسم الله الرحمن الرحيم 
السلام عليكم ورحمة الله وبركاته اعضاء المنتدى الكرام

الموضوع بلغة C#

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


تقديم :

تقنيه LINQ ليست فقط لقواعد البيانات ، في الحقيقة هذه التقنيه تتعامل مع اي فئة تتضمن الواجهة IEnumerable اي قابلة للعد ، وهذا يشمل المصفوفات Arrays و القوائم generic lists

تتضمن هذه الواجهة طرق كثيرة جدا للتعامل مع البيانات ، مثل Select , Where , Aggregate وغيرها الكثير والكثير

لذلك فكرت انه من باب التطبيق نقوم بعمل مثال يقوم بانشاء استعلام SQL بناء على بيانات الجدول المختارة من المستخدم ، او ما يصطلح الاخوة على تسميته "صانع اكواد"

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

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


مفاهيم اساسية خارج LINQ : 


  1. string interpolation الادخال وسط النصوص : 

    تتيح لنا هذه الميزة ادخال القيم وسط النصوص بطريقة سهلة جدا واكثر امانا ، 
    مثلا اذا كان لدينا متغير اسمه i نريد ان ندخله وسط قيمة نصية فان المطلوب هو ان تسبق القيمة النصية ب العلامة $ وان تضع المتغير داخل قوسين {} :

كود :
Dim str As String = $"I'm {i} years old"

المطلوب :

 قيمة من نوع String تمثل نص الاستعلام بالشكل التالي حسب الصفوف المختارة :

PHP كود :
SELECT [Col1],[Col2],[Col3FROM [TableWHERE [Col1]='Value' AND [Col2]='Value' 


البداية :

نبدأ بتصميم بسيط يؤدي الغرض :

   

لاحظ الداتا جريد فيو قمنا باضافة 4 اعمدة لها عبارة عن : 
  • اسماء الاعمدة ،
  • هل هذا العمود داخل في جملة SELECT ،
  • هل هذا العمود داخل في قيمة WHERE ،
  • اذا كان داخل في جملة WHERE ما القيمة المطلوبة للشرط
الكود : 

دعونا اولا نفكر فيما سنحتاجه ،

صيغة الاستعلام التي نريدها تتكون من كلمات ثابتة : "SELECT" و "FROM" و "WHERE"  

وكلمات مغيرة : اسماء الحقول المختارة بعد SELECT وكذلك الشروط الموضوعة بعد WHERE وكذلك اسم الجدول

طيب لذلك سنقوم بتعريف 4 متغيرات من نوع String 
  • tableName : وهو يمثل اسم الجدول المطلوب انشاء قيمة استعلام له
  • selects : الحقول المطلوبة محاطة ب [] و مفصول بينها ب ,
  • wheres : حقول الشروط محاطة ب [] ايضا ومتبوعة بالقيمة على شكل ='value' و كذلك مفصول بينها ب AND
  • sqlCommand : نخزن فيه الاستعلام المنشأ

هيا بنا في حدث btnGenerateSql.Click نعرف متغير اسم الجدول ونسند له قيمة من مربع النص الخاص باسم الجدول محاط بالاقواس [] :


كود :
       Dim tableName As String = $"[{txtTableName.Text}]"


كيف نحصل على القيمة المطلوبة للمتغير selects ؟

طيب نبدأ العمل الحقيقي الان ، نريد الحصول على صفوف الداتا جريد فيو على شكل IEnumerable من نوع DataGridViewRow لنتمكن من استخدام طرق LINQ عليها ،

لفعل ذلك نستخدم الطريقة Cast ونمرر لها النوع DataGridViewRow :


كود :
       Dim selects = dgvTable.Rows.
           Cast(Of DataGridViewRow)()


جميل جدا ، الان ركزو معي جيدا ، نريد اختيار الصفوف المختارة فقط كجزء من Select ، اي الصفوف التي فيها قيمة الخلية الثانية ب True ، 

لفعل ذلك نحن بحاجة الى الطريقة Where ، التي هي دالة الاختيار ، وظيفتها انها تختار من عناصر بيانات العناصر التي توافق شرط معين ، تقبل مدخل تعبير لمدا يمثل الشرط الذي يتم الاخيار بناء عليه ، وهو في هذه الحالة قيمة الخلية الثانية من الصف الحالي x.Cells(1).Value 


   

كود :
       Dim selects = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(1).Value)


الان حصلنا على الصفوف المطلوبة فقط ، جميل جدا نريد الان الحصول منها على اسماء الاعمدة المطلوبة ( قيمة الخلية الاولى في الصف ) محاطة ب [] ،

لفعل ذلك نستخدم الدالة Select التي تسمي دالة التحويل ، وظيفتها انها تحول كل العناصر التي تطبق عليها الى صورة اخرى ، في حالتنا نريد تحويل عناصر صفوف الداتا جريد فيو DataGridViewRow الى قيم نصية String تمثل اسماء الاعمدة ، الدالة تقبل مدخل تعبير لمدا يمثل التحويل المطلوب على كل عنصر ، وهو في هذه الحالة قيمة الخلية الاولى محاطة باقواس $"[{x.Cells(0).Value}]"


   

كود :
       Dim selects = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(1).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]")


طيب جميل جدا الان ماذا اذا لم يختار المستخدم اي صف ؟ في هذه الحالة تكون القائمة فارغة ، نريد في هذه الحالة ان تكون القيمة الافتراضية "*" هي العنصر الوحيد ، يعني في حالة لم يتم اختيار صف معين نحن سنعيد القيمة * التي تعني كل الاعمدة في SQL  ، 

لفعل ذلك نستخدم الدالة  DefaultIfEmpty التي وظيفتها انها ترجع بعنصر وحيد عبارة عن القيمة الافتراضية التي تمررها لها في حالة كانت القائمة التي تطبق عليها فارغة ، في هذه الحالة نمرر لها القيمة "*"


كود :
       Dim selects = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(1).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]").
           DefaultIfEmpty("*")


طيب الان جميل جدا جدا جدا ، معنا قائمة فيها كل اسماء الاعمدة المختارة ، محاطة باقواس [] وفي حالة لم تيم اختيار شيء معنا * ،

الخطوة القادمة هي تجميع عناصر هذه القائمة في قيمة نصية واحدة مفصول بينهم ب ,

لفعل ذلك نستخدم الدالة Aggregate التي وظيفتها تجميع عناصر القائمة في قيمة واحدة ، تأخد مدخل تعبير لمدا ذو مدخلين ومخرج واحد

يطلب منك اذا كان لديك هذين العنصرين (x,y) مثلا كيف تقوم بتجميعهم ؟ 

نخبره اننا نريده ان يضع القيمة الاولى متبوعة بفاصلة متبوعة بالقيمة الثانية 

كود :
Function(x, y) $"{x},{y}"


كود :
       Dim selects = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(1).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]").
           DefaultIfEmpty("*").
           Aggregate(Function(x, y) $"{x},{y}")


حسنا الان انتهينا من المطلوب للمتغير selects ، الان وقت مناسب جدا لاخذ كوب ساخن من الشاي الثقيل عديم السكر  Big Grin 

انتهيت ؟ مرحبا بك مجددا  Smile 

بقي لنا ان نحصل على قيمة المتغير wheres 

نبدأ مثلما بدأنا سابقا ، نحول العناصر باستخدام Cast :


كود :
Dim wheres = dgvTable.Rows.
           Cast(Of DataGridViewRow)()


نختار الصفوف المحددة فقط في الخلايا الثالثة ( CheckBox الخاص ب Where ) 

كود :
       Dim wheres = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(2).Value)



   

بعد ذلك نحصل على قيم الصفوف المطلوب عمل شرط بها وكذلك احاطتها باقواس [] واضافة قيمة الشرط لها ='value'
الكود التالي نخبره ان يحول كل عنصر من القائمة الى ما نريده :


كود :
       Dim wheres = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(2).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]='{x.Cells(3).Value}'")


لاحظ ان x.Cells(0).Value تمثل اسم العمود بينما x.Cells(3).Value تمثل قيمة الشرط بعد Where=


   
   

نجعل القيمة الافتراضية 1=1 ، في حالة ليس هناك عناصر شرط نريد جلب الكل في الاستعلام :

كود :
       Dim wheres = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(2).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]='{x.Cells(3).Value}'").
           DefaultIfEmpty("1=1")


واخيرا تجميع العناصر والفصل بينهم  ب AND

كود :
       Dim wheres = dgvTable.Rows.
           Cast(Of DataGridViewRow)().
           Where(Function(x) x.Cells(2).Value).
           Select(Function(x) $"[{x.Cells(0).Value}]='{x.Cells(3).Value}'").
           DefaultIfEmpty("1=1").
           Aggregate(Function(x, y) $"{x} AND {y}")


اخر خطوة هي وضع العناصر في متغير الاستعلام :

كود :
        Dim sqlCommand As String = $"SELECT {selects} FROM {tableName} WHERE {wheres}"

وبعد ذلك اخراجها للمستخدم : 

كود :
        txtSql.Text = sqlCommand

حسنا انتهينا فعلا ،

النتيجة :


   

مع عدم اختيار اي شيء :


   

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


الملفات المرفقة
.zip   MiniSqlGeneratorVB.zip (الحجم : 55.66 ك ب / التحميلات : 92)
الرد }}}


الردود في هذا الموضوع
تطبيق على طرق LINQ - صانع اكواد SQL صغير mini SQL generator - بواسطة Anas Mahmoud - 07-09-20, 10:13 AM

المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
Big Grin [مشروع] تصميم محرر اكواد بسيط من خلال الفيجوال بيسك مع السورس كود ahmadpal 1 2,117 23-01-24, 05:38 PM
آخر رد: alkndy
  برنامج صانع الاكواد الاصدار المجاني الجديد aljzazy 27 20,083 14-01-24, 12:39 PM
آخر رد: mahmoued2022
Information [VB.NET] سورس كود لمشروع ادارة كوفي شوف صغير.. under development musalem 0 641 04-07-23, 01:56 AM
آخر رد: musalem
Heart [مشروع] نسخه مصغره من برنامج صانع الاكواد للجميع aliday03 19 19,191 12-10-22, 12:11 PM
آخر رد: aliday03
Lightbulb سورس كود برنامج صانع الاكواد asemshahen5 60 48,002 16-02-22, 06:54 PM
آخر رد: ibrahematia
  برنامج صانع الاكواد لقواعد البيانات من نوع SQL Server Compact 3.5 Codack 1 1,842 04-10-21, 02:07 AM
آخر رد: وعد مولود
  [مشروع] تصميم تطبيق لقفل واخفاء الملفات مع السورس كود ahmadpal 11 6,303 10-11-20, 06:41 PM
آخر رد: djtech
  تصميم برنامج صانع الشهادات التقديرية عبد الهادي بهاب 0 2,326 05-09-20, 06:17 PM
آخر رد: عبد الهادي بهاب
  [مشروع] تصميم تطبيق بسيط لسورة البروج ( التزامن بين الصوت و النص ) عبد الهادي بهاب 0 1,093 03-09-20, 03:06 AM
آخر رد: عبد الهادي بهاب
  ممكن Generator code abarrak 3 2,456 03-08-20, 01:31 AM
آخر رد: حريف برمجة

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


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