• 0
Eng.Tareq Jehad

Entity Framework with WPF | Lesson 01

سؤال

بسم الله الرحمن الرحيم Entity Framework with WPF

 

بداية أحبذ لو يتم قراءة المقال من ملف [PDF] لكون التنسيق به أفضل[http://www.4shared.com/office/wr0MBEiQ/Entity_Framework_with_WPF.html].

كان من المفترض أن تبدأ سلسلة WPF بمكوناتاها والانتقال تدريجيا من موضوع لآخر، ولكن نظراً لكون أكثر البرامج تطبيقاً هي تلك اللي تتعامل مع قواعد البيانات، فقد جاء هذا الدرس، حيث سنعالج أكثر المشاكل التي تنتج عن برامج قواعد البيانات، ولبيان أهيمة WPF في بناء تطبيقات كهذه، وهو ما سوف يحفزك عزيزي القارىء إلى الانتقال إلى بيئة WPF لتطوير مشاريع مهما كانت، بأجمل وأقوى أسلوب، وبأقل سطور كود ممكنة كما سنلاحظ في مثالنا الحالي حيث سيتم اختصار الكود المكتوب إلى ما دون العشرة أسطر!!.

في واقع الأمر هناك عدة منهجيات لعمل تطبيقات قواعد البيانات مع WPF، ولكي يتناسب محتوى المقال مع عنوانه، سوف نقوم بإنشاء تطبيق بأحدث ما تقدمه لنا WPF من ميزات، وإذا مررنا على أحد المفاهيم الجديدة، فسوف يأتي شرحها لاحقاً في المقالات القادمة إن شاء الله تعالى، فكل ما يهمنا حالياً هو بناء التطبيق الذي يتعامل مع قاعدة البيانات. والإستفادة منه قدر الإمكان، سوف نقوم بعمل المراحل التالية لإتمام المشروع:

1.      تصميم قاعدة البيانات الخاصة بنا.

2.      إنشاء مشروع WPF جديد، و إنشاء طبقة التعامل مع قاعدة البيانات، Entity Framework Model.

3.      إختبار المشروع.

1. تصميم قاعدة البيانات:

سوف نقوم بعمل قاعدة بيانات جديدة ونسميها [Shop] ونقوم بعمل جدولين[Category] و [Product]، ونربط بينهما للإستفادة من موضوع الربط بين الجداول، بعد عمل قاعدة البيانات الجديدة، نقوم بتصميم الجداول كالشكل التالي، مراعاة وضع حقل [Id] كمفتاح رئيسي [Primary Key]، ووضع خاصيته [IsIdentity] ضمن نافذة [Column Properties] إلى [Yes] في الجدولين، ليصبح لدينا الشكل التالي:

 

a2D0N08.png

 

والأن نقوم بإنشاء العلاقة بينهما، حيث نلاحظ أن جدول [Product] يحوي على حقل [CategoryId] التابع للجدول الاخر [Category]، حالياً العلاقة افتراضية فقط، لذلك سوف نقوم بالربط كالتالي:

نقوم بالضغط بالزر الإيمن على مساحة فارغة بجوار جدول [Product]، ونختار من القائمة الخيار الرابع [RelationShips...]، تظهر واجهة صغير فارغة نقوم بالضغط على زر [Add] لإضافة علاقة جديدة، فتظهر لدينا بعض المعلومات في النافذة التي تحوي خصائص العلاقة هناك الحقل الثاني يسمى [Tables And Columns Specifications] بجانبة يظهر زر [...]، نضغظ عليه، الأن نقوم بتحديد جدول العلاقة الرئيسي وحقله، وتحديد جدول العلاقة الثانوي وحقله كالتالي:

 

8wZCpvm.png

 

نضغط على موافق، لنعود للواجهة السابقة، نجد حقل بالخصائص اسمة [INSERT And UPDATE Specification]، نقوم بفتحة فنجد هناك خياران الاول [Delete Rule] والثاني [Update Rule]، نقوم بتحديد  قيمة الخيار الاول [Delete Rule] ونضعها [Cascade]، لكي تتم عمليات المسح بالتوافق.

هكذا يكون لدينا قاعدة بيانات علائقية مربوطة مع بعضها بشكل منطقي. نضغط على زر []، ونقوم بحفظ العمل للانتقال إلى المرحلة الثانية.

2. إنشاء مشروع WPF جديد:

نقوم بفتح [Visual Studio] ونعمل [File> New> Project] ونختار نوع اللغة [Visual C#] ونوع المشروع [Wpf Application]، نقوم بتسمية المشروع [EntityFrameworkWithWPF]، ثم نضغط على موافق.

الأن سوف نقوم بجزء مهم من العمل وهو إضافة طبقة البيانات [Data Access Layer] إلى مشروعنا، وبالطبع هذه الطبقة هي []، الذي سيقدم لنا خدمات مميزة للتعامل مع البيانات. لذلك نقوم بإضافة عنصر جديد للمشروع [Add New Item]، ونختار [ADO.NET Entity Framework Model]. ونقوم بتسميه [Shop].

 

3H32WEK.png

 

بعدها سوف تظهر لنا نافذة لتحديد نوع [Model]، نقوم باختيار [Generate from database]، سوف نقوم بشرح النوعين وأوقات استخدامهن في المقالات القادمة بإذن الله.

 

 

OBcpYRM.png

 

نضغط على [Next]، الأن سوف تظهر نافذة أخرى لتحديد الاتصال مع قادة البيانات، نضغط على [New Connection...]، وبعدها سوف تظهر نافذة اخرى لتحديد الاتصال. نقوم أولا بإدخال إسم [Server]، وثم نختار إسم قاعدة البيانات التي قمت بإنشاءها قبل قليل. وبالتالي يصبح لدينا الشكل التالي، بإعتبار أني استخدمت [SQLEXPRESS].

 

blJx5WT.png

 

يمكننا اختبار الاتصال بالضغط على زر [OK]. وبعد التحقق من نجاح الاتصال، نضغط على موافق للعودة للنافذة السابقة والتي تكون قد اخذت إعدادات الاتصال الجديد، نضغط على [Next]، بعدها تظهر لنا نافذة مميزة، تحوي على ثلاث عناصر أساسية هي: [Tables]، [Views] ، و[Stored Procedures and Functions]، وهي واضحة المعالم، ما يهمنا حالياً هو أن نختار الجداول التي أنشاءها مسبقاً لذلك نفتح الخيار [Tables] ونحدد الجدولين الخاصين بنا كالتالي:

 

xDiGbMT.png

 

نضغط على [Finish]، وننتظر حتى يتم إنشاء [Model]، الخاص بقاعدة البيانات خاصتا، بعدها سيظهر لنا الجدولين مربوطين مع بعضهما البعض وهذا المكان يسمى [Conceptual Model]، او مكان التصميم حيث يمكننا التعديل بما يناسبنا، وهناك العديد من الخيارات يمكننا عملها مع هذا التصيم، مثلا يمكننا عمل علاقات وراثة مع الجداول، او تعريف أنواع بيانات جديدة مركبة، كل هذا سنشاهده في المقالات القادمة بإذن الله.

ملاحظة: كما تحدثنا مسبقاً هناك عدة طرق او منهجيات لتطبيق هذا المشروع ضمن [WPF]، سوف ننطلق من منهجية بسيطة نوعاً مع العلم أن هناك طرق أخرى تختصر علينا الكثير العمل وكتابة الكود، ولكننا بحاجة لتسلسل منطقي من الأبسط إلى الأعقد بالإضافة لبعض المفاهيم الواجب فهمها.

الأن سوف نقوم تصميم واجهة عمل تتكون من [ListBox]، لعرض البيانات الحالية ومجموعة من العناصر لعرض تفاصيل كل عنصر على حدة، ومجوعة من الأزار للتحكم بالبيانات. سوف تصبح لدينا النافذة كالشكل التالي:

 

uLxCiLa.png

 

وإليك عزيزي القارئ كود [XAML]، لهذه النافذة والذي يحوي على بعض المعلومات الهامة جداً، سوف نناقشها بعد قليل.

<Window x:Class="EntityFrameworkWithWPF.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        WindowStartupLocation="CenterScreen"        Title="MainWindow" Height="379.767" Width="441.653" Loaded="Window_Loaded">    <Grid Background="WhiteSmoke">        <Grid.RowDefinitions>            <RowDefinition Height="auto"/>            <RowDefinition Height="*"/>            <RowDefinition Height="auto"/>        </Grid.RowDefinitions>        <TextBlock Grid.Row="0"  Margin="5">            <Run Text="Categories "/>            <Hyperlink Name="lnkNew" Click="lnkNew_Click">New</Hyperlink>        </TextBlock>        <ListBox Grid.Row="1" Name="lstCategories" DisplayMemberPath="Name" SelectionChanged="lstCategories_SelectionChanged"/>        <Grid Grid.Row="2" Name="gridDetails" Margin="10" >            <Grid.RowDefinitions>                <RowDefinition Height="auto"/>                <RowDefinition Height="auto"/>                <RowDefinition Height="auto"/>            </Grid.RowDefinitions>            <Grid.ColumnDefinitions>                <ColumnDefinition Width="auto"/>                <ColumnDefinition/>            </Grid.ColumnDefinitions>            <TextBlock Grid.Row="0" Grid.Column="0" Text="ID: " Margin="5"/>            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Id}" Margin="5"/>            <TextBlock Grid.Row="1" Grid.Column="0" Text="Name: " Margin="7"/>            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Name}" Margin="5"/>            <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">                <Button Name="btnAdd" Content="Add" Width="75" Margin="5" Click="btnAdd_Click"/>                <Button Name="btnUpdate" Content="Update" Width="75" Margin="5" Click="btnUpdate_Click"/>                <Button Name="btnDelete" Content="Delete" Width="75" Margin="5" Click="btnDelete_Click"/>            </StackPanel>        </Grid>    </Grid></Window>

لم يسعفني محرر الأكود في هذه الصفحة من عرض كود [] بالتنسيق المطلوب ولكن ما يهمنا هو بعض الاسطر للشرح:

·        DisplayMemberPath="Name"

نلاحظ وجود هذه الخاصية ضمن [ListBox]، وفائدتها أننا سنربط الـ [ListBox]، مع مجموعة من [Categories objects] قادمة من قاعدة البيانات وحيث انه لا توجد طريق معينة لعرض هذه [Categories objects] لذلك نقوم بتحديد الخاصية المراد عرضها من ضمن مجوعة [Categories objects] القادمة، لذلك وضعنا القيمة [Name].

·        Text="{Binding Path=Id}"  

·        Text="{Binding Path=Name}"

هنا فائدة عظيمة تقدمها لنا [WPF]، حيث نقوم بتحديد نوع النص الذي سيظهر عند تشغيل البرنامج واحضار الـ [Categories] من قاعدة البيانات، وتوفر علينا هذه الخاصية الكثير مع عمليات تجميع البيانات وربطها، أو تحويلها من نوع لأخر، ففي أغلب الأحيان نقوم بإحضار قيمة من [TextBox] معين ومن ثم تحويلها إلى [double] مثلاً لتتناسب مع قاعدة البيانات، هنا لا يوجد داعي لأي من هذه الأعمال المستهلكة للوقت. يكفي أن تفهم فهما مبدئيا معنى هذا الحديث، لأن كل هذا سيشرح في مقالات [Data Binding] الخاصة بسلسلة [WPF] إن شاء الله تعالى.

بعد أن تقوم بتعديل كود النافذة, وتعمل [Build] للمشروع للتأكد من عدم وجود أخطاء معينة، تأتي مرحلة كتابة بعض أسطر الكود لإتمام العمل، وكما تحدثت في السابق ليس علينا كتابة الكثير من الكود. ولا ننسى وجود طرق تختصر أيضا الكثير عما سنقوم به حالياً ولكنني سأتركة كما تحدث لبعد الحديث عن عدة مفاهيم.

الأن نقوم بعرض كود [C#] للنافذة الحالية من خلال [View> Code]، هنا سنقوم بإدخال بعض أسطر كود [C#]، وللعلم لن تستطيع تشغيل البرنامج حتى تضيف كامل هذه الاسطر البرمجية، لانه سيعطيك بعض الأخطاء مثل أن هناك حدث معين معرف ضمن [XAML] ولا يوجد ضمن [C# code]، لذلك اضف هذه الاسطر أولاً.

  •   نقوم بتعريف [object] من نوع طبقة البيانات التي عرفناها مسبقا، وهو ما سيمكننا من التخاطب مع قاعدة البيانات وإجراء العمليات اللازمة. وسيكون التعريف وموقعه لدينا كالتالي: 
 ShopEntities db = new ShopEntities();        public MainWindow()        {            InitializeComponent();                   } 
  •    نقوم بإضافة حدث تحميل النافذة [Window_Load]، والذي سيقوم بإحضار بيانات [Categoies] من قاعدة البيانات وعرضها ضمن [ListBox] وسيكون شكل الحدث كالتالي.
private void Window_Loaded(object sender, RoutedEventArgs e)        {            db.Categories.Load();            lstCategories.ItemsSource = db.Categories.Local;        } 
  •    الأن نقوم بإضافة الحدث الخاص بإنشاء [Category] جديد، ربما يختلف نوع الكود المكتوب عن ما هو متعارف عليه ولكن لاحظ سهولة العمل في البداية وسيكون كل شيء بخير بعدها.
  private void lnkNew_Click(object sender, RoutedEventArgs e)        {            gridDetails.DataContext = new Category();            gridDetails.Children[3].Focus();        } 
  •   الأن سنقوم بإضافة الحدث الخاص بإضافة العنصر الجديد إلى قاعدة البيانات، وهو الخاص بزر [Add] وسيكون كالتالي:
 private void btnAdd_Click(object sender, RoutedEventArgs e)        {            Category c = (Category)gridDetails.DataContext;            db.Categories.Add(c);            db.SaveChanges();        } 

·        الأن الحدث الخاص بالتعديل، أي زر [Update]، بكل بساطة سيكون كالتالي:

 private void btnUpdate_Click(object sender, RoutedEventArgs e)        {            db.SaveChanges();        } 

·        وفي النهاية الحدث الخاص بالحذف، زر [Delete] سيكون كالتالي:

   

       

  private void btnDelete_Click(object sender, RoutedEventArgs e)        {            Category c = (Category)gridDetails.DataContext;            if (MessageBox.Show("Do you want to delete " + c.Name + " ?") == MessageBoxResult.OK)            {                db.Categories.Remove(c);                db.SaveChanges();            }        } 

هكذا نكون انتيهنا من العمل الكامل. الأن بإمكانك تشغيل البرنامج [F5]، بالطبع لا يوجد بيانات حالياً. لذلك عليك بالضغظ على [New] وادخال إسم العنصر الجديد ومن ثم [Add]، وقم بتجريب باقي الخدمات.

قمت بإدخال ثلاث عناصر جديدة إلى قاعدة البيانات، وكانت كالتالي:

 

Juvlt9P.png

 

بعد تحديد عنصر من ال [ListBox]، يمكنك تعديل قيمتة أو حذفها، أو كما تحدثنا الضغط على [New] لادخال عنصر جديد ثم [Add] لحفظه.

في المرة القادمة إن شاء الله سنتعلم كيف نتعامل مع الجدول الثاني [Product]، الذي لم نتعامل معه في هذا المثال التوضيحي، وسنقوم أيضا بعرض بياناتنا الحالية بشكل أفضل بمساعدة [WPF]، وكمثال على ذلك:

 

FknVjr1.png

 

في الأسفل المشروع مع كامل مع [scripts]، الخاص بقاعدة البيانات.

ولكم أفضل التحية.

 

http://www.4shared.com/rar/wW-sWGtp/EntityFrameworkWithWPF.html

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

7 إجابة على هذا السؤال .

  • 0

بارك الله فيك الدرس ممتع ورغم أني أعمل على Silverlight وبتقنيات MVVM ,MVP  منذ 2011 إلا أنني استمتعت جدا بالقراءة والتطبيق

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

ما هي DataContext وماذا تعني مقارنة بـWinform  ولماذا لم نختر SelectedItem وما هي أفضليتها.

ما هي نسخة EF  التي تستعملها EF3,4? لأنني لم أستخدم EF  بحياتي مع Local or Load فأنا سابقا (ولا زلت ) إن استخدمت Pure Entity Framework استخدم datacontecxt نفسها لجلب البيانات كمثال

private void Window_Loaded(object sender, RoutedEventArgs e)        {                       lstCategories.ItemsSource = db.Categories.ToList();        } 

أرجو أن تستخدم Resources DataTemplate  في مرحلة متقدمة وليس فقط DataTemplate  داخل الـListBox  حتى يتسنى للمتابع العمل على Resources و Key

الشكر الجزيل لك على هذه المعلومات المفيدة

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ما يميز wpfعن windows form غير الشاشة الروسمية هل من شيء مميز

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ما يميز wpfعن windows form غير الشاشة الروسمية هل من شيء مميز

 

  • بالتأكيد! وهناك الكثير لكن الأهم:
  • امكانية استخدام الشاشة لأكثر من منحى فقط عليك بتعيين DataContext مناسبة
  • جرب التعامل مع WPF على Interoperability 
  • جرب ربط البيانات عن طريق DataBindings
  • إذا اردت عدم استخدام الكود الخلفي يمكنك تطبيق مواضيع MVVM ,MVP وحاليا MVVM  هي المفضلة لمن يعمل في إطار Frameworks XAML
  • التعامل مع الـ Sokets بطريقة أقوى وأمن بكثير عبر تطبيقات WCF , الدعم المستمر والسهولة في انشاء الكنترولات كما تريد
  • الكثير الكثير من العناوين العريضة التي لا يسعنا ذكرها أو تفصيلها في الرد
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

اكرمك الله اخوتي

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بارك الله فيك الدرس ممتع ورغم أني أعمل على Silverlight وبتقنيات MVVM ,MVP  منذ 2011 إلا أنني استمتعت جدا بالقراءة والتطبيق

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

ما هي DataContext وماذا تعني مقارنة بـWinform  ولماذا لم نختر SelectedItem وما هي أفضليتها.

ما هي نسخة EF  التي تستعملها EF3,4? لأنني لم أستخدم EF  بحياتي مع Local or Load فأنا سابقا (ولا زلت ) إن استخدمت Pure Entity Framework استخدم datacontecxt نفسها لجلب البيانات كمثال

private void Window_Loaded(object sender, RoutedEventArgs e)        {                       lstCategories.ItemsSource = db.Categories.ToList();        } 

أرجو أن تستخدم Resources DataTemplate  في مرحلة متقدمة وليس فقط DataTemplate  داخل الـListBox  حتى يتسنى للمتابع العمل على Resources و Key

الشكر الجزيل لك على هذه المعلومات المفيدة

نعم أخي كل ما سألت عنه هو محل سؤال بالنسبة للقارىء. أنا وضعت هذا المثال كمثال توضيحي عن WPF خصوصا مع ربطها بطبقة البيانات [Entity Framework Model]، بالنسبة للنسخة التي اعمل عليها هي النسخة السادسة، ولكن طريقة جلب البيانات، صحيحة بالطريقتين، سواء التي عملت عليها المثال، او التي تحدث عنها أنت، ولكن عندما نستخدم [CollectionSourceView]، فنحن بحاجة للطريقة التي استخدمها أنا، لان مصدر البيانات يكون معرف ضمن [XAML] وهو بحاجة لتحميل البيانات أولاً ثم استخدامها،[لم استخدم هذا المفهوم بهذا المثال، وهو مفهوم كما اخبرت ضمن الشرح انه بحاجة لبعض المفاهيم سنمر عليها] وسيأتي شرحها في الدروس القادمة إن شاء الله، وكذلك باقي أسئلتك أخي الكريم، وكما قلت لك المثال عبارة عن نظرة عامة، لمن يحب أن يعمل تطبيق حديث نوعا ما مستخدما احدث التقنيات، لك كل التحية والتقدير.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ما يميز wpfعن windows form غير الشاشة الروسمية هل من شيء مميز

طبعاً للوهلة الأولى أو الحديث العام عن [WPF]، يكون دائما حول القوة الرسومية وهذا لا يتخلف عليه اثنان، ولكن الجدير بالذكر أن [WPF]، تضم مجموعة من [Libraries]، تقدم خدمات رائعة جداً، من ناحية التعامل مع الوثائق [Documents]، يعني بإمكانك إنشاء برنامج لقراءة الملفات يشبة [PDF]، بكل سهولة، وعندما عرضت [WPF]، تقنية الوثائق هذه التقنية ضجة عالمية. 

 

ولدينا في [WPF] ايضا الـ [Validations] و الـ [Converters]، بالإضافة لـ [Resources]، والتي تمكنك من الوصول السريع والمختصر للبيانات بعدة طرق فمثلا يمكنك عمل برنامج متعدد اللغات بكل سهولة باستخدام [Dynamic Resources]، هناك ايضاً الـ [Data Providers] ويتم تطوير المزيد من هذا المزايا عليها حالياً وأعطيك مثال عليها. إذا كان لديك ملف

، وتريد جلب بياناته وعرضها على واجهة معينة كل ما عليك هو تعريف [XmlDataProvider] ضمن [XAML]، ويمكن تعريفه ضمن الـ [Resources]، وبالتالي الوصول السريع إليه في إي لحظة.

 

هناك العديد والعديد من المزيا، لا يسعنا ذكرها هنا ولكننا سنمر عليها مع مرور الوقت إن شاء الله، ولكن مع هذا لا ننسى أن قوة [WPF] الرسومية اذهلت المصميمين. لك كل الشكر اخي الكريم, وترقب المقالات القادمة إن شاء الله.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

اكرمك الله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .