تحديث Update السجلات في ADO.NET in ASP.NET Core Application

-

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

نبدا بالانتقال الى View المسمى AllStudent الي تم انشاءه سابقا، تذكر ان في هاذا View عملنا على عرض بيانات الطلاب داخله مع إضافة button لغاية الحذف. سنقوم هنا بإضافة عمود جديد لغاية التعديل يحتوي على  update link ، وعند النقر فوق هذا update link  يتم إعادة توجيه المستخدم إلى View أخرى تسمى Update.cshtml حيث يمكن تحديث القيم القديمة بأخرى جديدة.

تمام نشوف كيف بنطبق هذا الكلام.

اولا نعدل على View المسمى AllStudent بالكود التالي:

@model List<StudentsModel>
<link href="~/lib/bootstrap/dist/css/bootstrap.css.map" rel="stylesheet" />
<table class="table table-bordered table-sm table-striped">
    <thead>
        <tr>
            <th scope="col">Student No</th>
            <th scope="col">FullName</th>
            <th scope="col">Birthday</th>
            <th scope="col">Address</th>
            <th scope="col">UserName</th>
            <th scope="col">Email</th>
            <th scope="col">Mobile</th>
            <th scope="col">CreatedDate</th>
            <th scope="col">Update</th>
            <th scope="col">Del</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var student in Model)
        {
        <tr>
            <td>
                @student.StudentNo
            </td>
            <td>
                @student.FullName
            </td>
            <td>
                @Convert.ToDateTime(@student.Birthday).ToString("dd/MM/yyyy")
            </td>
            <td>
                @student.Address
            </td>
            <td>
                @student.UserName
            </td>
            <td>
                @student.Email
            </td>
            <td>
                @student.Mobile
            </td>
            <td>
                @*@Convert.ToDateTime(@student.CreatedDate).ToString("dd/MM/yyyy")*@
                @string.Format("{0:dd MMMM yyyy}", @student.CreatedDate)
            </td>
            <td>
                <a onclick="DeleteStudent(@student.StudentID);" class="btn btn-danger small">Delete</a>
            </td>

            <td><a asp-action="Update" asp-route-id="@student.StudentID" class="btn btn-success small">Update</a></td>
        </tr>
        }
    </tbody>
</table>
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
التعديل هو اضفنا  th element جديدًا داخل العنصر thead:
<th scope="col">Update</th>
أضفت أيضًا td element جديدًا داخل حلقة foreach:

<td><a asp-action="Update" asp-route-id="@student.StudentID" class="btn btn-success small">Update</a></td>

الكود asp-action="Update"  عبارة عن Built-In Tag Helpers in ASP.NET Core والتي تم استخدامها هنا داخل href attribute في anchor tag  حيث تم ربطها مع Update Action ، بناءً على نظام التوجيه الخاص بالمشروع.
للاحظ كمان ان أضفنا الكود
asp-route-id="@student.StudentID" 
إلى anchor tag  بحيث تم إضافة Id   الخاص بالطالب الذي سيتم النقر فوقه الى قيمة href.
سيتم ترجمة الأوامر السابقة عند التنفيذ في المتصفح الى الكود التالي:
<a href /Students/Update/1">Update</a>
<a href=" /Students/Update/2">Update</a>
<a href=" /Students/Update/3">Update</a>
انظر الصورة في الأسفل: 


نحتاج الان إلى إنشاء Update Actions (GET and POST type) في StudentsController .
طبق الكود التالي في هاذا action 

        public IActionResult Update(int Id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            StudentsModel studentsModel = new StudentsModel();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Select * From Students Where StudentId='{Id}'";
                SqlCommand command = new SqlCommand(sql, connection);
                connection.Open();
                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        studentsModel.FullName = Convert.ToString(dataReader["FullName"]);
                        studentsModel.StudentNo = Convert.ToString(dataReader["StudentNo"]);
                        studentsModel.Birthday = Convert.ToDateTime(dataReader["Birthday"]);
                        studentsModel.Address = Convert.ToString(dataReader["Address"]);
                        studentsModel.UserName = Convert.ToString(dataReader["UserName"]);
                        studentsModel.Email = Convert.ToString(dataReader["Email"]);
                        studentsModel.Mobile = Convert.ToString(dataReader["Mobile"]);
                        studentsModel.CreatedDate = Convert.ToDateTime(dataReader["CreatedDate"]);
                    }
                }
                connection.Close();
            }
            return View(studentsModel);
        }
        [HttpPost]
        public IActionResult Update(StudentsModel studentsModel, int Id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Update Students SET FullName='{studentsModel.FullName}', Birthday='{studentsModel.Birthday}', Gender='{studentsModel.Gender}', Nationality='{studentsModel.Nationality}', Address='{studentsModel.Address}', UserName='{studentsModel.UserName}', Password='{studentsModel.Password}', Email='{studentsModel.Email}', Mobile='{studentsModel.Mobile}', Note='{studentsModel.Note}' Where StudentId='{Id}'";
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    connection.Open();
                    command.ExecuteNonQuery();
                    connection.Close();
                }
            }
            return RedirectToAction("AllStudent");
        }

شرح الكود:
تم تعريف Update Action Method الأولى من نوع HTTP GET  حيث تم ارسال parameter الأول من نوع int باسم StudentId يحتوي على رقم الطالب، والتي تم ارساله عن طريق URL.
على سبيل المثال - إذا كان عنوان URL هو
 Students/Update/1
في هذه الحالة تكون قيمة parameter الخاصية برقم الطالب تساوي 1.
يقوم ASP.NET Core بهذا الشيء تلقائيًا بواسطة تقنية Model Binding.
بعد هيك عملنا استعلام SQL باستخدام StudentId باستخدام الكود:
string sql = $"Select * From Students Where StudentId='{Id}'"; 
يعمل هذا الكود على جلب البيانات الخاصة برقم الطالب StudentId الذي تم إرساله فقط 
بعد ذلك، نقوم بتنفيذ هذه query باستخدام SqlCommand object ثم نستخدم SqlDataReader object لقراءة البيانات الخاصة برقم الطالب المرسل، 
تم تعريف متغير من نوع StudentsModel، نقوم بملء البيانات من الامر SqlDataReader داخل هذا المتغير، وفي الاخر ننرسل هذا المتغير ك Model الى View 
الكود الذي يعمل على ذلك هو :

public IActionResult Update(int Id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            StudentsModel studentsModel = new StudentsModel();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Select * From Students Where StudentId='{Id}'";
                SqlCommand command = new SqlCommand(sql, connection);
                connection.Open();
                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        studentsModel.FullName = Convert.ToString(dataReader["FullName"]);
                        studentsModel.StudentNo = Convert.ToString(dataReader["StudentNo"]);
                        studentsModel.Birthday = Convert.ToDateTime(dataReader["Birthday"]);
                        studentsModel.Address = Convert.ToString(dataReader["Address"]);
                        studentsModel.UserName = Convert.ToString(dataReader["UserName"]);
                        studentsModel.Email = Convert.ToString(dataReader["Email"]);
                        studentsModel.Mobile = Convert.ToString(dataReader["Mobile"]);
                        studentsModel.CreatedDate = Convert.ToDateTime(dataReader["CreatedDate"]);
                    }
                }
                connection.Close();
            }
            return View(studentsModel);
        }

في Update Action Method الثاني عملنا تعريف الو من نوع HttpPost بهف اجراء التعديل على البيانات،والي بنعملو هنا : تحديث بيانات الطالب الذ تم ارجاع بياناته في الطريقة السابقة. في هذا action نستقبل 2 arguments وكلاهما يحصل على قيمته من ميزة model، وهذه arguments  هي:
StudentsModel studentsModel.
سنحصل على قيمتها من form الذي سيرسله المستخدم في Update View
int StudentId.
سنحصل على قيمته من عنوان URL.

تمام في هذا action، نقوم بإنشاء update SQL Query  حيث عملنا استقبال القيم التي يرسلها المستخدم في form من داخل View، والتي يتم توفيرها في طريقة Update View:

الكود التالي هو الذي يقوم بذلك: 
string sql = $"Update Students SET FullName='{studentsModel.FullName}', Birthday='{studentsModel.Birthday}', Gender='{studentsModel.Gender}', Nationality='{studentsModel.Nationality}', Address='{studentsModel.Address}', UserName='{studentsModel.UserName}', Password='{studentsModel.Password}', Email='{studentsModel.Email}', Mobile='{studentsModel.Mobile}', Note='{studentsModel.Note}' Where StudentId='{Id}'";
بعد ذلك، يتم تنفيذ SQL query  هذا بواسطة SqlCommand object:
الكود الذي يعمل ذلك
using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    connection.Open();
                    command.ExecuteNonQuery();
                    connection.Close();
                }
في السطر الأخير، سنقوم بإعادة توجيه المستخدم إلى AllStudent Action  بحيث نتمكن من رؤية القيم المحدثة.
return RedirectToAction("AllStudent");
تبقي إضافة Update View داخل مجلد Views ➤ Students.

ثم أضف الكود التالي: 

model StudentsModel
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ADO - Update Inventory</title>
    <link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
</head>
<body>
    <div class="container-fluid">
        <h1>Update an Inventory <a asp-action="Index" class="btn btn-sm btn-secondary">Back</a></h1>
        <form method="post">
            <div class="form-group">
                <label>FullName:</label>
                <input class="form-control" asp-for="FullName" />
                <span asp-validation-for="FullName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Birthday:</label>
                <input class="form-control" asp-for="Birthday" />
                <span asp-validation-for="Birthday" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Gender:</label>
                <select class="form-control" asp-for="Gender">
                    <option value="M">Male</option>
                    <option value="F">Female</option>
                </select>
                <span asp-validation-for="Gender" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Nationality:</label>
                <select class="form-control" asp-for="Nationality">
                    <option value="M">Jordan</option>
                    <option value="F">Saudi Aribae</option>
                    <option value="F">UAE</option>
                </select>
                <span asp-validation-for="Nationality" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Address:</label>
                <input class="form-control" asp-for="Address" />
                <span asp-validation-for="Address" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>UserName:</label>
                <input class="form-control" asp-for="UserName" />
                <span asp-validation-for="UserName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Password:</label>
                <input class="form-control" asp-for="Password" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Email:</label>
                <input class="form-control" asp-for="Email" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Mobile:</label>
                <input class="form-control" asp-for="Mobile" />
                <span asp-validation-for="Mobile" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label>Note:</label>
                <input class="form-control" asp-for="Note" />
                <span asp-validation-for="Note" class="text-danger"></span>
            </div>
            <div class="text-center panel-body">
                <button type="submit" class="btn btn-sm btn-primary">Update</button>
            </div>
        </form>
    </div>
</body>
</html>
يمكنك الآن اختبار Update functionality. قم بتشغيل مشروعك وانقر فوق رابط التحديث الخاص بأحد السجلات ، ثم قم بإضافة بعض التغييرات:
ستكون نتيجة الصفحة كالتالي: 

انقر فوق الزر تحديث لحفظ التغييرات. ستتم إعادة توجيهك إلى AllStudent View حيث ستجد السجلات محدثة الآن. 

وبهيك بنكون خلصنا الدرس