لا يمكنك انشاء مشروع جديد يا حبيبي !

30 08 2009

في يوم حالك السواد ، قمت بتشغيل حاسوبي لأجد مجموعة من المشاكل الغريبة في النظام – ويندوز فيستا – حيث ان متصفح الانترنت Internet Explorer 8 كل بضعه دقائق ينبهني بأن برنامجا حاول تعديل محرك البحث الرئيسي فيه ، وبعض البرامج لا تعمل كما يجب ، توجهت بعدها إلى Visual Studio 2008 وهناك كانت المفاجأه ! لا يوجد أي قالب Tamplate لأي نوع من المشاريع في أي لغة سواء VB او C# وبالتالي لا يمكن انشاء أي مشروع جديد ! ولا حتى اضافه أي عنصر جديد إلى أي مشروع موجود مسبقا ! وفي كل مره تظهر امامي الرسالة التالية :

"No template information found. See the application log in Event Viewer for more details. To open Event Viewer, click Start, click Control Panel, double-click Administrative Tools, and then double-click Event Viewer."

توجهت إلى مستعرض الاحداث Event Viewer فوجدت الرسالة التالية :

the global template information is out of date. Regenerate the templates by running ‘devenv.exe /installvstemplates’ or reinstalling the application.

فور قراءتي للرسالة السابقه ، توجهت إلى محرر الاوامر في ويندوز Command Promote وكتبت ما يلي الاوامر التالية سطرا بسطر :

cd \

cd c:\Program files\Microsoft visual Studio 9.0\common7\IDE

devenv.exe /installvstemplates

بعد تلك السطور انحلت المشكله وعادت المياه إلى مجاريها !

تحياتي





حقول الهوية : بين الفئات البرمجية وحقول SQL Server :

23 08 2009

يوجد الكثير من الطرق التي لعمل حقول هوية مميزة Identity fields او ما يعرف بالمفتاح الأساسي Primary Key Filed ، من اشهرها على الاطلاق حقل الـ Autoincrement او الترقيم التلقائي ، والتي يتم فيها توليد رقم تلقائي يزيد عن اخر رقم في العداد الخاص بقيمة تكون في اغلب الاحيان 1 ، تتميز بالخفة والنحافه ، وبالتالي فنحن نتوقع منها الاداء المتميز كونها تحمل قيمة رقمية صغيرة تبدأ من 1 وتصل للآلاف لكنها قد تصل الملايين كلما كبر حجم البرنامج وزاد استخدامه ، وان يكن ، فهي لاتزال ارقام صحيحه integers قد تكون مثلا 99999999999953424 وماذا يعني ذلك ؟ فلا يوجد مشاكل حتى اللحظه فما احلاها !

ولكن ما يعيب هذا الاسلوب هو افتقادها إلى شيء مهم للغاية ، حيث اننا في التطبيقات الكبيرة نوعا ما ، يكون اغلب اعتمادنا على الوضع المنفصل فقد نستخدم Dataset,LINQtoSQL,Entity Framework,…etc ونضيف سجلات Records وقد يتم تعديلها حتى قبل ان ترسل إلى قاعدة البيانات database ، والمشكلة التي ستحدث هنا ، ان كائنات البيانات التي بحوزتنا لن تستطيع اسناد قيمة لحقل المفتاح الأساسي ، حيث ان اصدارها يتم حكرا على قاعدة البيانات فقط ، ولن نستطيع معرفة قيمتها الا بإضافة السجلات إلى قاعدة البيانات وهنا تمكن المشكلة ، ففي التطبيقات التجارية والتطبيقات التي تعتمد على تعدد الطبقات n-tier applications ، يتم اضافة العديد من السجلات وحزمها كلها في حزمة واحده لإرسالها دفعة واحدة إلى قاعدة البيانات ، كما يتم قبل ذلك كله تبادل البيانات بين طبقتي العرض والاعمال ، ناهيك عما يدور خلف الكواليس من عمليات تحقق وسين وجيم !

أقرأ باقي الموضوع »





3- استخدام الـ Entity Framework لتطوير نوافذ من النوع MasterDetails:

10 08 2009

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

نقوم بداية بإضافة فئة جديدة من النوع ADO.NET Entity data Model ونسميها مثلا CustomerOrdersModel ثم يظهر امامنا المعالج طالبا منا تحديد كيفية تصميم مصدر البيانات لنطلب منه توليد النموذج بكرم من قاعدة البيانات :

الخطوة التالية ، يطلب منك المعالج تحديد قاعدة البيانات ، قم بتحديد قاعدة البيانات Northwind بنفسك ، ثم انتقل إلى الخطوة التي بعدها وحدد الجدولين Customer,Orders ، وفي خانة الـ Namespace اكتب اسم دلالي مميز سنحتاجه لاحقا وليكن Entities ، انه المعالج بعدها ، لتفتح لك نافذة جديدة وهي نافذة الـ ModelDesigner ، طبعا لا حاجه لك في تعديل أي شيء هناك :

 

لكنني اود اخبارك بأنه يفضل ل كان تغير قيمة الخاصية Entity Container Name والتي تمثل اسم الفئة الحاضنة لجداول قاعدة البيانات ، فهي التي سنستخدمها دوما في اكوادنا ، ففي حالة احتواء مشروعك على عدة نماذج Models من هذا النوع فقد يتكرر الاسم عليك ويسبب لك شيء من الارتباك البرمجي .

الآن توجه إلى النافذة الجديدة Form1 لنقوم بتطوير نافذة Master Details من النوع Full Details ، سنحتاج اولا إلى اضافة الـ DataSource ، وهنا تشترك الطريقتان LINQ-to-SQL و EntityFramework في كون الطريق هي نفسها ، حيث تختار ان يكون مصدر البيانات هو كائن Object ثم تحدد الفئة Customer وتنهي المعالج كالعادة لتجد الفئات قد وجدت على شكل جداول في النافذة Datasources ، قم بعدها بسحب الجدول Customer على شكل Details إلى النافذة from1 ثم الجدول Orders الفرعي التابع له النافذة ايضا ! بعدها انتقل مباشرة إلى نافذة محرر الاكواد حيث اننا سنحتاج إلى كتابة سطيرات برمجي بسيطة :

Public Class Form1
   
Dim ent As New Entities

    Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load

        Me.CustomersBindingSource.DataSource = ent.Customers.Include("Orders")

    End Sub

    Private Sub CustomersBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles CustomersBindingNavigatorSaveItem.Click
       
Me.CustomersBindingSource.EndEdit()
       
Me.ent.SaveChanges()

    End Sub

حيث نقوم اولا بتعريف كائن جديد من النوع Entities وهي الفئة التي تحضن باقي فئات الجداول في الـ Entity Framework ، وفي حدث التحميل نقوم باسناد قيمة إلى الكائن BindingDataSource ولكن هنا لدي ملاحظه مهمه جدا ، وهي ضرورة استخدام الطريقة Inculde وارسال إسم الجدول المرتبط معها ، حيث لو كتبت ent.Customers فإن سجلات الجدول الفرعي Orders لن تظهر وانما ستظهر البيانات الاساسية فقط من الجدول الاب Customers .

وبالنسبة لحفظ التعديلات فكما نلاحظ فإننا لا نحتاج إلا إلى مناداة الطريقة SaveChanges حتى يتولى عنك خلفان وعباس وحمدان القيام بالباقي !

بالنسبة لتطوير نموذج من النوع Lookup List فلا اعتقد انك ترغب في اعادة كل السطور من الدرسين الماضيين وتغيير كلمه واحده فقط في كل مره !





2- استخدام مزود LINQ-to-SQL

4 08 2009

استخدام مزود LINQ-to-SQL لا يختلف كثيرا عن استخدام Dataset الا في بعض الخطوات البسيطة ، كما سنرى الآن :
في البداية ، نقوم بإضافة فئات LINQ-to-SQL وذلك بالتوجه إلى القائمة Project | Add New Project Item ثم اختيار LINQ-to-SQL Classes واعطها الاسم CustomerOrders ، ستظهر امامك نافذة خالية ، سنحتاج ان نقوم بسحب الجداول المطلوبة إلى الجزء الايسر منها من نافذة Server Explorer ، لذلك اذهب إلى نافذة server Explorer وافتح قاعدة البيانات من هناك او اضفها إلى تلك القائمة من خلال الزر Connect to Database . بعد قيامك بهذا ، قم بسحب الجدولين Order,Customers إلى الجزء الايسر من نافذة الـ O/R Designer التي ظهرت قبل قليل ، وستلاحظ انشاء الجدولين هناك على شكل فئات كما بالصورة التالية :

بهذا نكون قد هيئنا فئات LINQ-to-SQL للعمل عليها ، ننتقل الان إلى تصميم النافذة الاولى ، وهي التي تتبع النمط Full Detailed ، سنتوجه بداية إلى النافذة Data Sources ونقوم بإضافة مصدر بيانات جديد لكن انتبه عندما يظهر امامك المعالج اختر الخيار Objects وليس Database كما بالصورة التالية :

وذلك لاننا سنختار ان يكون مصدر البيانات هو الفئات التي ولدها الـ O/R Designer وليس قاعدة البيانات مباشرة .
في المرحلة التالية من المعالج ، اختر الفئة Customer كما بالصورة التالية :

قم بعدها بإنهاء المعالج بالخيار Finish مباشرة ، الآن ستظهر كل حقول الجدول Customer على شكل فئة وخصائص تابعة لها وكذلك فئة فرعية بالإسم Orders وهي تمثل الجدول Orders التابع للجدول Customer بعلاقة من النوع One-to-Many كما بالشكل التالي :

يمكنك الان التعامل مع تلك الفئات مباشرة مثلما عملنا مع Dataset في مرة الماضية ، حيث قم بسحب الفئة customer إلى النافذة على شكل Details ، ثم قم بسحب الجدول Orders التابع لها ايضا إلى النافذة ، هنا سنحتاج إلى خطوة اضافية بسيطة وهي تعبئة الفئة Customer بالبيانات ، حيث ان الفئة الحالية ستكون وكأنها مجرد مخطط لا اكثر نستخدمه في انشاء الادوات والربط بينها بسهولة ، توجه إلى محرر الاكواد واكتب الكود التالي :

Public Class Form1
    
Dim db As New CustomerOrdersDataContext

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _ 
System.EventArgs) Handles MyBase.Load
        
Me.CustomerBindingSource.DataSource = db.Customers

    End Sub

    Private Sub CustomerBindingNavigatorSaveItem_Click(ByVal sender As _ 
System.Object, ByVal e As System.EventArgs) Handles _ CustomerBindingNavigatorSaveItem.Click
        
Me.CustomerBindingSource.EndEdit()
        
Me.db.SubmitChanges()
    
End Sub
End Class

 

الكائن db يمكنك اعتباره ممثل لجداول قاعدة البيانات الموجودة في الـ O/R Designer ويمكنننا من خلاله الوصول إلى الفئات التابعة له ( المقابلة للجداول ) والتحكم بها كما سنرى ،

في الحدث form_load نقوم بإسناد الفئة db.Customers لتكون هي مصد البيانات في الـ CustomersBindingSource ، وفي حدث CustomerBindingNavigatorSaveItem_Click الذي يتم تفجيره بمجرد نقر زر الحفظ نستخدم ذات الكائن ليقوم بإرسال كل التغييرات التي طرأت على البيانات سواءا كانت هذه التغييرات اضافة ، حذف او حتى تعديل بسطر واحد فقط !

بهذا نكون جاهزين لتشغيل التطبيق وتجربة النموذج الجديد !

بناء نموذج من نوع Lookup List :
لا اعتقد انك بحاجه إلى اعادة مجموعة من الاسطر كتبناها في حديثنا عن تطوير نافذة من النوع Lookup List باستخدام dataset ولا اعتقد ايضا انك بحاجه إلى اعادة كتابة سطرين صغيرين كتبناهما قبل حوالي 10 اسطر ! لذلك سأكتفي هنا بعرض المثال مباشرة .