السلام عليكم ورحمة الله وبركاته
اخي الكريم يجب ان تعلم كيف يعمل Entity Framework وان تعلم ان الطريقة الامثل للتعامل معه هي بمجاراته فيما يريد هو وليس ما نريد نحن
تقديم هام قبل الاجابة
Entity Framework مصمم ليمكنك من التعامل مع البيانات على شكل كائنات Objects وهو مفهوم ال ORM بحيث يكون الجدول هو عبارة عن DbSet قابل للعد ، والحقل الواحد هو كائن من نوع البيانات الذي قمت بتعريفه Entity ، يمكنك التعامل معه بشكل مباشر بالكود
وبالتالي اذا فمت بتصميم فئاتك بشكل سليم فيمكنك الوصول الى ما تريد باسط الطرق
لا اعلم شكل هيكل بياناتك ولكني للمثال فقط سافترض ان لديك Entity واحدة ( جدول واحد ان صح التعبير ) اسمها Book وبها الخصائص ( الاعمدة ) التالية :
كود :
Public Class Book
Public Property ID As Integer
Public Property Title As String
Public Property Author As String
Public Property AddedDate As Date
Public Property Pages As Integer
End Class
وان الكلاس الذي يرث من DBContext اسمه libraryContext
كود :
Imports System.Data.Entity
Public Class libraryContext
Inherits DbContext
Public Property Books As DbSet(Of Book)
End Class
طيب جميل الان بعد ان قمنا ببناء الهيكل ، تحتاج طبعا كما تعلم لاضافة Migration لبناء قاعدة البيانات فعلا ، جميل جدا
الان يجب ان تعلم ان التعامل مع قاعدة البيانات من خلال Entity Framework يتم من خلال الكلاس الذي يرث من DBContext الذي قمنا بتعريفه ، وهو في حالتنا هنا كلاس libraryContext ،
ويجب ان تعلم ايضا ان DBContext ليس مصمما لان تظل نسخة منه موجودة طول عمل البرنامج ، انما الطريقة الصحيحة هو عمل نسخة منه عند الحاجة للتعامل مع قاعدة البيانات ومن ثم رميها عند الانتهاء من الامر باستخدام Using :
كود :
Using db As New libraryContext
'هنا تفعل ما نريده من قاعدة البيانات
End Using
الان يمكنك التعامل مع db.Books على انها جدول الكتب ، تضيف او تمسح او تعدل ما تريده ثم تستدعي db.SaveChanges
الجميل هنا ان db.Books هي بكل بساطة IEnumerable(of Book) وهذا يعني انه الان تستطيع استخدام تقنية Linq عليه ! وهو اساس ما سنقوم به لاحقا
الاجابة :
الان الطريقة الابسط لتحقيق ما تريد هو عن طريق تعريف متغير عام من نوع Book نسميه CurrentBook ، نضع به السجل الحالي ( ان صح التعبير )
كود :
Dim CurrentBook As Book
الان لايجاد السجل التالي ، نحن نريد اول سجل يكون قيمه ID اكبر من الحالي ، لعمل ذلك نستخدم LINQ
كود :
Sub NextBook()
Using db As New libraryContext
Dim n As Book = (From b In db.Books
Where b.ID > CurrentBook.ID
Order By b.ID Ascending
Select b).FirstOrDefault
If n IsNot Nothing Then CurrentBook = n
End Using
End Sub
لاحظ الترتيب التصاعدي Ascending وكذلك FirstOrDefault التي تعيد اول عنصر من الاستعلام اذا كان يحتوي على عناصر او Nothing اذا كان فارغا
وكذلك الامر للذهاب للسجل السابق ، نريد اخر سجل له ID اصغر من الحالي ، نفس الكود السابق ولكن الترتيب تنازلي وكذلك الشرط اصغر من :
كود :
Sub PreviousBook()
Using db As New libraryContext
Dim p As Book = (From b In db.Books
Where b.ID < CurrentBook.ID
Order By b.ID Descending
Select b).FirstOrDefault
If p IsNot Nothing Then CurrentBook = p
End Using
End Sub
للذهاب لاول سجل نحتاج لترتيب الكل تصاعدي ثم اخذ اول عنصر :
كود :
Sub FirstBook()
Using db As New libraryContext
Dim f As Book = (From b In db.Books
Order By b.ID Ascending
Select b).FirstOrDefault
If f IsNot Nothing Then CurrentBook = f
End Using
End Sub
للذهاب لاخر سجل نحتاج للترتيب تنازلي ثم اخذ اول عنصر :
كود :
Sub LastBook()
Using db As New libraryContext
Dim l As Book = (From b In db.Books
Order By b.ID Descending
Select b).FirstOrDefault
If l IsNot Nothing Then CurrentBook = l
End Using
End Sub
الى هنا اجبت على سؤالك ،
لتكملة المثال ، اضف ازرار للسابق والتالي والاول والاخير ، وكذلك للتعديل والحدف والاضافة ،
وكذلك اضف خانات TextBox و DateTimePicker و NumericUpDown مناسبة ، وعدل اسمائها لتصبح ذات دلالة
الان سنعرف اجراء لملء الخانات من السجل الحالي :
كود :
Sub Populate()
If CurrentBook Is Nothing Then Return
txtID.Text = CurrentBook.ID
txtTitle.Text = CurrentBook.Title
txtAuthor.Text = CurrentBook.Author
dtpAddedDate.Value = CurrentBook.AddedDate
nudPages.Value = CurrentBook.Pages
End Sub
في حدث Load نريد الذهاب الى اول سجل :
كود :
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FirstBook()
Populate()
End Sub
الان احداث الضغط على الازرار ،
زر التالي :
كود :
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
NextBook()
Populate()
End Sub
زر السابق :
كود :
Private Sub btnPrev_Click(sender As Object, e As EventArgs) Handles btnPrev.Click
PreviousBook()
Populate()
End Sub
زر الاول :
كود :
Private Sub btnFirst_Click(sender As Object, e As EventArgs) Handles btnFirst.Click
FirstBook()
Populate()
End Sub
زر الاخير :
كود :
Private Sub btnLast_Click(sender As Object, e As EventArgs) Handles btnLast.Click
LastBook()
Populate()
End Sub
الان ازرار الحدف والاضافة والتعديل :
بنفس الطريقة لاضافة سجل جديد نقوم بانشاء كائن جديد من Book ونملئه بالبيانات ومن ثم نضيفه باستخدام DB.Books.Add
ثم نجعله هو السجل الحالي ونعيد ملء الخانات من جديد :
كود :
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Dim newBook As New Book
newBook.Title = txtTitle.Text
newBook.Author = txtAuthor.Text
newBook.Pages = nudPages.Value
newBook.AddedDate = dtpAddedDate.Value
Using db As New libraryContext
db.Books.Add(newBook)
db.SaveChanges()
End Using
CurrentBook = newBook
Populate()
End Sub
لتعديل البيانات نقوم بعمل Attach للسجل الحالي اولا ، وهو امر مهم حتى يتمكن من التعرف عليه ضمن السجلات الموجودة بالفعل ، ومن ثم نجري التعديلات المطلوبة ، ثم نعيد ملء الخانات مرة اخرى :
كود :
Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Using db As New libraryContext
db.Books.Attach(CurrentBook)
CurrentBook.Title = txtTitle.Text
CurrentBook.Author = txtAuthor.Text
CurrentBook.Pages = nudPages.Value
CurrentBook.AddedDate = dtpAddedDate.Value
db.SaveChanges()
End Using
Populate()
End Sub
لحدف السجل الحالي نقوم ايضا بعمل Attach اولا ثم نقوم بحذفه باستخدام db.Books.Remove ثم ننتقل للسجل التالي :
كود :
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Using db As New libraryContext
db.Books.Attach(CurrentBook)
db.Books.Remove(CurrentBook)
db.SaveChanges()
End Using
NextBook()
Populate()
End Sub
اتمنى ان تكون الفكرة وصلت خلف هذا المثال ، كان هذا باختصار شديد رغم الاطالة صدقني
اذا اردت تفاصيل اكثر عن جزئية ما تفضل
السلام عليكم ورحمة الله