ASP.NET MVC – Truy xuất dữ liệu từ Controller

Trong phần này bạn sẽ tạo ra lớp TaskController và viết mã để lấy về dữ liệu và hiển thị chúng lên trình duyệt bằng cách sử dụng view template.

Hãy mở dự án mà bạn đã làm sau đó hãy nhấn chuộc phải vào thư mục Controllers. Bạn chọn các tùy chọn như hình dưới đây:

imagetitle

Ở tùy chọn thứ 2, khi bạn chọn “Controller with read/write…”, thì Visual Studio sẽ tạo ra các CRUD actions cho controller để tạo, đọc, cập nhật xóa dữ liệu (CRUD ~ create, read, update, delete) với đối tượng model được xử lý ở đây là Task. Visual Studio sẽ sử dụng Entity Framework và TaskDbContext để tạo mã lệnh truy xuất database.

Sau khi bạn nhấn Add ở cửa sổ trên, Visual Studio sẽ tạo ra các tập tin và thư mục (được bôi vàng) ở hình dưới đây:

imagetitle

Hãy chạy ứng dụng và chuyển đến địa chỉ /Task bằng cách điều hướng trên thành địa chỉ của trình duyệt, lúc đó request sẽ được chuyển đến action mặc định của TaskController là Index. Và kết quả là một danh sách rỗng các tác vụ, bởi vì bạn chưa thêm bất cứ tác vụ nào vào.

imagetitle

Tạo một tác vụ

Bạn hãy chọn link Create New và được điều hướng đến /Task/Create và hãy điền thông tin về tác vụ, sau đó nhấn vào nút Create

imagetitle

Hãy nhấp vào nút Create để dữ liệu trong form được gởi lên server, ở đó thông tin của tác vụ sẽ được lưu trong database. Nếu bạn tạo thành công, trang web sẽ được điều hướng đến /Task/Index, ở đó bạn sẽ thấy được danh sách các tác vụ cần thực hiện:

imagetitle

Tất nhiên, khi thực hiện đến đây, bạn sẽ thấy một điểm khá buồn cười, đó là tại sao lại phải điền vào trường CreateDate, bởi ngày tạo có thể lấy được từ giờ của hệ thống, và ngày giờ hiển thị có vẻ không đẹp lắm. Và bạn cũng sẽ có nhiều câu hỏi tại sao, ví dụ như tại sao Visual Studio có thể tạo mọi thứ cho bạn như vậy? Hãy thử khám phá các chức năng khác như Details (xem chi tiết), Edit (cập nhật), Delete (xóa), các chức năng này đều hoạt động, và sau đó hãy cùng trải nghiệm mã lệnh được tạo ra bởi Visual Studio nhé.

Trải nghiệm mã lệnh được sinh ra bởi Visual Studio

Mở tập tin Controllers/TaskController.cs và xem action Index, phương thức Index được cài đặt như sau:

private TaskDbContext db = new TaskDbContext();

        //
        // GET: /Task/

        public ViewResult Index()
        {
            return View(db.Tasks.ToList());
        }

Bạn có thể thấy rằng, action Index đã trả về dữ liệu trực tiếp bằng phương thức View (một phương thức có sẵn của lớp Controller) và tham số truyền vào cho phương thức chính là danh sách các tác vụ được lấy lên từ database bằng TaskDbContext.

Entity Framework là một cải tiến vượt bậc khi bạn chỉ cần gọi một thuộc tính và có thể lấy lên hết tất cả các dòng dữ liệu. Tuy nhiên nếu bạn đã quen thuộc với lập trình thì bạn thấy mã lệnh được tạo ra như thế này thì thực sự không ổn, bởi không ai lấy lên hết toàn bộ các dòng của một bảng dữ liệu như trên cả, nếu đó là một bảng có hơn 10.000 dòng hoặc hơn 1 triệu dòng, thì thật tội nghiệm cho ứng dụng của bạn vì sẽ phải chờ đợi rất lâu.

Câu hỏi bạn sẽ đặt ra lúc này có thể là, vậy model ở đây là gì, câu trả lời model chính là kết quả trả về của db.Tasks.ToList(), tức là danh sách các Task được lấy lên từ database.

Strongly Typed Models (model được ép kiểu mạnh) và từ khóa @model

Ở trong một bài học trước đó, chúng ta đã biết rằng, controller có thể truyền dữ liệu đến view thông qua đối tượng ViewBag hoặc ViewData, tuy nhiên có một vấn đề khi sử dụng hai đối tượng này (tuy hai mà một) là ứng dụng sẽ không biết được các đối tượng có chứa những gì, và mã lệnh có đúng hay không cho đến khi ứng dụng chạy. Nếu lập trình sơ sót, khả năng sinh lỗi là rất cao.

ASP.NET MVC cũng cung cấp khả năng để truyền các đối tượng có kiểu rõ ràng cho view. Với cách thức như vậy, ứng dụng sẽ được kiểm tra kỹ càng trong thời gian biên dịch và đồng thời Visual Studio cũng sẽ kiểm tra tính đúng của model cho bạn bằng tính năng Intellisense. Chúng ta đang sử dụng model có kiểu mạnh với TaskControlller và view Index.cshtml.

Bằng cách sử dụng dòng @model bên trong tập tin view template, bạn có thể quy định kiểu của đối model mà view sẽ nhận được, lúc đó view sẽ hiểu model được nhận có kiểu gì. Khi xem dòng đầu tiên của view Index.cshtml bạn sẽ thấy :

@model IEnumerable<ToDoApp.Models.Task>

Khai báo @model giúp cho view dễ dàng truy xuất đến danh sách tác vụ mà controller truyền đến thông qua thuộc tính Model của view. Nhờ vậy, trong Index.cshtml, chúng ta dễ dàng duyệt qua danh sách các tác vụ mà thuộc tính Model lưu giữ:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Content)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CreateDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.DueDate)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}

Bởi vì đối tượng Model là đối tượng có kiểu mạnh (ở đây là kiểu IEnumerable), mỗi đối tượng item điều được định kiểu là Task. Điều đó có nghĩa là, VisualStudio với tính năng Intellisense sẽ hỗ trợ hiển thị các thuộc tính của đối tượng khi bạn sử dụng code editor (trình soạn thảo mã lệnh).
Làm việc với SQL Server Compact

Entity Framework Code First sẽ tự tìm chuỗi kết nối tương ứng trong tập tin Web.config ngay bên trong thư mục gốc của ứng dụng, nếu database không tồn tại, Entity Framework sẽ tạo mới database. Bạn có thể kiểm chứng bằng cách mở thư mục App_Data, bạn sẽ thấy tập tin Todo.sdf, đó là tập tin database của SQLCE.

Hãy đưa tập tin thành một phần của dự án, bằng chọn biểu tượng “Show all files” và “Refresh”, sau đó nhấp chuột phải lên tập tin Todo.sdf và chọn “Include in project”.

imagetitle

Nhấp đôi chuột phải lên Todo.sdf để mở Server Explorer. Sau đó mở rộng mục Tables để xem các bảng đã được tạo ra:

imagetitle

Lưu ý: bạn nhớ đọc bài hướng dẫn cài đặt những thứ cần thiết để lập trình với ASP.NET MVC. Nếu bạn chưa cài đặt SQL Server Compact 4.0 thì bạn sẽ bị báo lỗi khi nhấp đôi chuột vào.

Có hai table (bảng) được tạo ra, một là dành cho lớp Task, table thứ hai là EdmMetadata, table này dùng để lưu vết nhằm giúp Entity Framework biết rằng database và các entities (các lớp ánh xạ dữ liệu) chưa được đồng bộ hóa với nhau. (Ví dụ như bạn thêm một trường là Description trong lớp Task).

Nhấp chuột phải vào table Tasks và chọn “Show Table Data” bạn sẽ thấy danh sách các Task mà bạn đã tạo ra:

imagetitle

Nhấp chuột phải vào table Tasks và chọn “Edit Table Schema”:

imagetitle

Lúc này bạn sẽ thấy cửa số Edit Table sẽ xuất hiện, ở đó bạn có thể thay đổi cấu trúc của table, tuy nhiên hãy cẩn trọng, bởi table Tasks là do Entity Framework tạo ra, nếu bạn thay đổi table này, bạn cần phải cập nhật lại lớp Task để đảm bảo Entity Framework có thể ánh xạ giữa table và entity.

imagetitle

Khi bạn đã xong các thao tác với database, bạn hãy đóng kết nối (close connection). Bởi vì nếu không, khi bạn chạy ứng dụng, ứng dụng sẽ báo lỗi không kết nối được, lỗi đó là do Visual Studio đang kết nối đến database mà ứng dụng mong muốn thao tác với nó.

imagetitle

Như vậy bạn đã có database, và bạn đã biết cách để tạo ra controller có khả năng tương tác với database nhờ một chút “ảo thuật” của Visual Studio và Entity Framework.