![]() |
|
[C#.NET] تطبيق على طرق LINQ - صانع اكواد SQL صغير mini SQL generator - نسخة قابلة للطباعة +- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb) +-- قسم : قسم لغة السي شارب C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=175) +--- قسم : قسم امثلة ومشاريع C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=179) +--- الموضوع : [C#.NET] تطبيق على طرق LINQ - صانع اكواد SQL صغير mini SQL generator (/showthread.php?tid=36317) |
تطبيق على طرق LINQ - صانع اكواد SQL صغير mini SQL generator - Anas Mahmoud - 07-09-20 بسم الله الرحمن الرحيم السلام عليكم ورحمة الله وبركاته اعضاء المنتدى الكرام الموضوع بلغة VB لايخفى عليكم اخواني الكرام اهمية وقوة تقنية LINQ ، فهذه التقنية جعلت التعامل مع البيانات اسهل بكثير جدا ، فما كان يتطلب عديد السطور لانجازة اصبح الان يكفي سطر واحد لعمله تقديم : تقنيه LINQ ليست فقط لقواعد البيانات ، في الحقيقة هذه التقنيه تتعامل مع اي فئة تتضمن الواجهة IEnumerable اي قابلة للعد ، وهذا يشمل المصفوفات Arrays و القوائم generic lists تتضمن هذه الواجهة طرق كثيرة جدا للتعامل مع البيانات ، مثل Select , Where , Aggregate وغيرها الكثير والكثير لذلك فكرت انه من باب التطبيق نقوم بعمل مثال يقوم بانشاء استعلام SQL بناء على بيانات الجدول المختارة من المستخدم ، او ما يصطلح الاخوة على تسميته "صانع اكواد" ويجب قبل البدأ ان اخبركم ان الهدف من هذا المثال هو التدرب على استخدام LINQ وليس هو شرح كيفية عمل برنامج صانع اكواد ، فهذا موضوع قد قتل بحثا من جانب الاخوة الكرام ولاجل الوصول الى ذلك بابسط طريقة ممكنة هناك بعض المفاهيم التي يجب ان نتفق عليها اولا : مفاهيم اساسية خارج LINQ :
كود : int number = (int?)i ?? 0;المطلوب : قيمة من نوع String تمثل نص الاستعلام بالشكل التالي حسب الصفوف المختارة : PHP كود : SELECT [Col1],[Col2],[Col3] FROM [Table] WHERE [Col1]='Value' AND [Col2]='Value' البداية : نبدأ بتصميم بسيط يؤدي الغرض : [attachment=25594] لاحظ الداتا جريد فيو قمنا باضافة 4 اعمدة لها عبارة عن :
دعونا اولا نفكر فيما سنحتاجه ، صيغة الاستعلام التي نريدها تتكون من كلمات ثابتة : "SELECT" و "FROM" و "WHERE" وكلمات مغيرة : اسماء الحقول المختارة بعد SELECT وكذلك الشروط الموضوعة بعد WHERE وكذلك اسم الجدول طيب لذلك سنقوم بتعريف 4 متغيرات من نوع String
هيا بنا في حدث btnGenerateSql.Click نعرف متغير اسم الجدول ونسند له قيمة من مربع النص الخاص باسم الجدول محاط بالاقواس [] : كود : string tableName = $"[{txtTableName.Text}]";كيف نحصل على القيمة المطلوبة للمتغير selects ؟ طيب نبدأ العمل الحقيقي الان ، نريد الحصول على صفوف الداتا جريد فيو على شكل IEnumerable من نوع DataGridViewRow لنتمكن من استخدام طرق LINQ عليها ، لفعل ذلك نستخدم الطريقة Cast ونمرر لها النوع DataGridViewRow : كود : var selects = dgvTable.Rowsجميل جدا ، الان ركزو معي جيدا ، نريد اختيار الصفوف المختارة فقط كجزء من Select ، اي الصفوف التي فيها قيمة الخلية الثانية ب True ، لفعل ذلك نحن بحاجة الى الطريقة Where ، التي هي دالة الاختيار ، وظيفتها انها تختار من عناصر بيانات العناصر التي توافق شرط معين ، تقبل مدخل تعبير لمدا يمثل الشرط الذي يتم الاخيار بناء عليه ، وهو في هذه الحالة قيمة الخلية الثانية من الصف الحالي x.Cells[1].Value [attachment=25595] كود : var selects = dgvTable.Rowsولكن اذا كان الخلية لم يتم الضغط عليها قيمتها تكون null ويرمي البرنامج ب خطأ ، لذلك نستخدم المعاملين ? و ?? لتلافي ذلك : كود : var selects = dgvTable.Rowsالان حصلنا على الصفوف المطلوبة فقط ، جميل جدا نريد الان الحصول منها على اسماء الاعمدة المطلوبة ( قيمة الخلية الاولى في الصف ) محاطة ب [] ، لفعل ذلك نستخدم الدالة Select التي تسمي دالة التحويل ، وظيفتها انها تحول كل العناصر التي تطبق عليها الى صورة اخرى ، في حالتنا نريد تحويل عناصر صفوف الداتا جريد فيو DataGridViewRow الى قيم نصية String تمثل اسماء الاعمدة ، الدالة تقبل مدخل تعبير لمدا يمثل التحويل المطلوب على كل عنصر ، وهو في هذه الحالة قيمة الخلية الاولى محاطة باقواس $"[{x.Cells[0].Value}]" [attachment=25596] كود : var selects = dgvTable.Rowsطيب جميل جدا الان ماذا اذا لم يختار المستخدم اي صف ؟ في هذه الحالة تكون القائمة فارغة ، نريد في هذه الحالة ان تكون القيمة الافتراضية "*" هي العنصر الوحيد ، يعني في حالة لم يتم اختيار صف معين نحن سنعيد القيمة * التي تعني كل الاعمدة في SQL ، لفعل ذلك نستخدم الدالة DefaultIfEmpty التي وظيفتها انها ترجع بعنصر وحيد عبارة عن القيمة الافتراضية التي تمررها لها في حالة كانت القائمة التي تطبق عليها فارغة ، في هذه الحالة نمرر لها القيمة "*" كود : var selects = dgvTable.Rowsطيب الان جميل جدا جدا جدا ، معنا قائمة فيها كل اسماء الاعمدة المختارة ، محاطة باقواس [] وفي حالة لم تيم اختيار شيء معنا * ، الخطوة القادمة هي تجميع عناصر هذه القائمة في قيمة نصية واحدة مفصول بينهم ب , لفعل ذلك نستخدم الدالة Aggregate التي وظيفتها تجميع عناصر القائمة في قيمة واحدة ، تأخد مدخل تعبير لمدا ذو مدخلين ومخرج واحد يطلب منك اذا كان لديك هذين العنصرين (x,y) مثلا كيف تقوم بتجميعهم ؟ نخبره اننا نريده ان يضع القيمة الاولى متبوعة بفاصلة متبوعة بالقيمة الثانية كود : (x, y) => $"{x},{y}"كود : var selects = dgvTable.Rowsحسنا الان انتهينا من المطلوب للمتغير selects ، الان وقت مناسب جدا لاخذ كوب ساخن من الشاي الثقيل عديم السكر انتهيت ؟ مرحبا بك مجددا بقي لنا ان نحصل على قيمة المتغير wheres نبدأ مثلما بدأنا سابقا ، نحول العناصر باستخدام Cast : كود : var wheres = dgvTable.Rowsنختار الصفوف المحددة فقط في الخلايا الثالثة ( CheckBox الخاص ب Where ) كود : var wheres = dgvTable.Rows[attachment=25597] بعد ذلك نحصل على قيم الصفوف المطلوب عمل شرط بها وكذلك احاطتها باقواس [] واضافة قيمة الشرط لها ='value' الكود التالي نخبره ان يحول كل عنصر من القائمة الى ما نريده : كود : var wheres = dgvTable.Rowsلاحظ ان x.Cells[0].Value تمثل اسم العمود بينما x.Cells[3].Value تمثل قيمة الشرط بعد Where= [attachment=25596] [attachment=25598] نجعل القيمة الافتراضية 1=1 ، في حالة ليس هناك عناصر شرط نريد جلب الكل في الاستعلام : كود : var wheres = dgvTable.Rowsواخيرا تجميع العناصر والفصل بينهم ب AND كود : var wheres = dgvTable.Rowsاخر خطوة هي وضع العناصر في متغير الاستعلام : كود : string sqlCommand = $"SELECT {selects} FROM {tableName} WHERE {wheres}";وبعد ذلك اخراجها للمستخدم : كود : txtSql.Text = sqlCommand;حسنا انتهينا فعلا ، النتيجة : [attachment=25599] مع عدم اختيار اي شيء : [attachment=25600] اتمنى اكون قد وفقني الله لتبسيط المعلومة ، انا جاهز للاسئلة بخصوص هذا الموضوع اتمنى ان ينتشر استخدام LINQ بين الاخوة العرب |