بداية أحبذ لو يتم قراءة المقال من ملف [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] في الجدولين، ليصبح لدينا الشكل التالي:

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

نضغط على موافق، لنعود للواجهة السابقة، نجد حقل بالخصائص اسمة [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].

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

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

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

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

وإليك عزيزي القارئ كود [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]، وقم بتجريب باقي الخدمات.
قمت بإدخال ثلاث عناصر جديدة إلى قاعدة البيانات، وكانت كالتالي:

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

في الأسفل المشروع مع كامل مع [scripts]، الخاص بقاعدة البيانات.
ولكم أفضل التحية.
http://www.4shared.com/rar/wW-sWGtp/EntityFrameworkWithWPF.html

يرفع من قيمة الموضوع واهمية الرد