[Entity Framework] Phần 6: Sử dụng chú thích dữ liệu (Data Annotation)

279 lượt xem 
 Cập nhật lần cuối: 14/08/2018 lúc 21:43:34
Thể loại: Entity Framework 

Ở các bài viết trước, bạn đã học 3 phương pháp gieo mã nguồn cho dự án Web bằng Entity Framework: Code First, Database First và Model First. Trong bài này, chúng ta sẽ tập trung vào việc tìm hiểu cách chú thích dữ liệu ở các trường thuộc tính thuộc các lớp mô hình đã gieo tương ứng với các bảng trong database.

Ở ví dụ bài này, chúng ta sẽ tạo 1 dự án MVC và gieo mã nguồn theo kiểu Database First. Lý do việc này là để bạn chủ động hơn với các thuộc tính và kiểu dữ liệu, cũng như nơi lưu trữ cơ sở dữ liệu. Ngoài ra bạn có thể tạo mã nguồn theo kiểu Code First hay Model First tùy ý.

Chuẩn bị dữ liệu: Tạo dự án MVC, database và gieo mã nguồn Entity Framework

Tạo dự án MVC

Mở Visual Studio, chọn File -> New -> Project, sau đó tạo 1 dự án Console tên là DammioEF, ngôn ngữ C#. Lý do tạo dự án MVC là giúp bạn có thể nhìn thấy kết quả xác nhận dữ liệu trên giao diện Web.

Sau đó, bạn chọn kiểu dự án Web là MVC và nhấn OK để Visual Studio tự động tạo dự án.

Kết nối và tạo database

Bước này bạn có thể tham khảo bài Phần 4: Tạo cơ sở dữ liệu trước (Database First)

Tiếp theo, ở dự án MVC, bạn chọn menu View -> Server Explorer để kết nối với database SQL trên giao diện Visual Studio mà không cần mở SQL Studio Management.

Khi bảng Choose Data Source hiện ra thì bạn chọn Microsoft SQL Server và nhấn Continue để tiếp tục.

Bước này, chọn Data Source là Microsoft SQL Server, nhấn OK để bảng cấu hình Add Connection hiện lên. Kế đến, chọn Server name là (local) và chọn tên database là DammioEF và nhấn OK. Sau đó, Visual Studio dò thấy bạn chưa tạo database này và hỏi có tạo hay không, bạn nhấn Yes.

Sau khi kết nối thành công, bạn sẽ thấy ở khung Server Explorer xuất hiện kết nối mới tới database DammioEF. Bạn chọn chuột phải lên kết nối này và chọn New Query.

Paste đoạn mã này vào tập tin SQLQuery1.sql mới tạo ra và nhấn Excute (Ctrl + Shift + E) để thực thi.

CREATE TABLE [dbo].[Blogs] ( 
    [BlogId] INT IDENTITY (1, 1) NOT NULL, 
    [Name] NVARCHAR (200) NULL, 
    [Url]  NVARCHAR (200) NULL, 
    CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC) 
); 
  
CREATE TABLE [dbo].[Posts] ( 
    [PostId] INT IDENTITY (1, 1) NOT NULL, 
    [Title] NVARCHAR (200) NULL, 
    [Date] DATETIME NULL, 
    [ImageURL] NVARCHAR (1000) NULL, 
    [Type] INT NULL, 
    [Content] NTEXT NULL, 
    [BlogId] INT NOT NULL, 
    CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC), 
    CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) 
 
REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
);

Gieo mã nguồn

Sau khi tạo database xong, bạn nhấn menu View -> Solution Explorer (hoặc phím tắt Ctrl + Alt + L) để mở cửa sổ Solution Explorer, chọn thư mục Models, chuột phải chọn Add -> New Item để mở cửa sổ Add New Item.

Sau đó, chọn mục Data (tay trái), chọn ADO.NET Entity Data Model và tên của mô hình là Dammio.edmx, cuối cùng nhấn Add.

Bạn chọn mục Generate from Database, nhấn Next, chọn tên kết nối trong App.Config là DammioEFEntities, tiếp tục nhấn Next. Tiếp theo, Visual Studio hỏi về phiên bản EF cần gieo, bạn cứ chọn Entity Framework 6.0 trở lên và nhấn Next.

Ở cửa sổ Entity Data Model Wizard, bạn chọn gieo toàn bộ bảng trong hình và nhấn Finish, vậy là xong.

Chú thích dữ liệu (Data Annotation)

Data Annotation

Trong .NET Framework, Data Annotation dùng để thêm phần ý nghĩa mở rộng vào dữ liệu thông qua các thẻ thuộc tính. Tính năng Data Annotation được Microsoft giới thiệu lần đầu ở .NET 3.5 tại namespace System.ComponentModel.DataAnnotations. Namespace này chứa các lớp dùng để định nghĩa thuộc tính mở rộng cho dữ liệu.

Các thuộc tính Data Annotation được phân chia thành 3 thể loại chính:

  • Thuộc tính xác nhận (Validation Attribute): dùng để thêm các tập luật xác nhận cho dữ liệu.
  • Thuộc tính hiển thị (Display Attribute): dùng để đặc tả cách dữ liệu từ một lớp được hiển thị ở giao diện.
  • Thuộc tính mô hình (Modelling Attribute): dùng để đặc tả mục đích sử dụng của lớp thành viên và mối quan hệ giữa các lớp.

Thêm thư viện DataAnnotations

Trở lại dự án, trước hết bạn mở tập tin Dammio.edmx để thấy rõ mô hình như sau:

Trong đó, bảng Blog có định dạng dữ liệu như sau:

  • PostId: kiểu int, khóa chính, tự tăng (bắt buộc phải có dữ liệu)
  • Title: tiêu đề Post, kiểu NVARCHAR tối đa 200 ký tự
  • Date: ngày tháng, kiểu DateTime
  • ImageURL: đường dẫn hình ảnh, kiểu NVARCHAR, tối đa 1000 ký tự
  • Type: loại Post, kiểu int
  • Content: nội dung Post, kiểu NTEXT
  • BlogId: ID của Blog, kiểu int, khóa ngoại (bắt buộc phải có dữ liệu)

Tiếp theo, bạn mở tập tin Models/Post.cs (Dammio.edmx/Post.cs) và thấy nội dung như sau:

namespace DammioEF
{
    using System;
    using System.Collections.Generic;
    
    public partial class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public Nullable<System.DateTime> Date { get; set; }
        public string ImageURL { get; set; }
        public Nullable<int> Type { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
    
        public virtual Blog Blog { get; set; }
    }
}

Đến đấy chúng ta tiến hành thêm các chú thích dữ liệu cho các thuộc tính trong lớp Post.cs. Trước hết thêm dòng using System.ComponentModel.DataAnnotations; và dòng using System.ComponentModel; để nhúng namespace DataAnnotations vào lớp Post.

namespace DammioEF
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel; // thêm mới
    using System.ComponentModel.DataAnnotations; // thêm mới
    ...

Định nghĩa thuộc tính hiển thị (Display attribute)

Để định nghĩa thuộc tính hiển thị, đơn giản bạn chỉ cần thêm dòng [DisplayName(“tên cần hiển thị”)] vào trước các thuộc tính cần hiển thị.

namespace DammioEF
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel;
    
    public partial class Post
    {
        public int PostId { get; set; }
        [DisplayName("Tieu De")]  // Thuộc tính hiển thị
        public string Title { get; set; }
        [DisplayName("Ngay Thang")] // Thuộc tính hiển thị
        public Nullable<System.DateTime> Date { get; set; }
        [DisplayName("Duong dan hinh anh")] // Thuộc tính hiển thị
        public string ImageURL { get; set; } 
        [DisplayName("Loai")] // Thuộc tính hiển thị
        public Nullable<int> Type { get; set; }
        [DisplayName("Noi Dung")] // Thuộc tính hiển thị
        public string Content { get; set; }
        public int BlogId { get; set; }
    
        public virtual Blog Blog { get; set; }
    }
}

Trong ví dụ trên, bạn có thể thấy thuộc tính Title có tên hiển thị là “Tieu De”, như vậy khi sử dụng lớp này hiển thị ra màn hình, bạn chỉ thấy được tên thuộc tính “Tieu De” thay vì Title.

Để thử nghiệm trên giao diện Web, bạn phải tạo giao diện MVC như sau. Chuột phải chọn thư mục Controllers, chọn Add -> Controller…, sau đó chọn chế độ tạo MVC5 Controller with views, using Entity Framework và nhấn nút Add.

Tiếp theo, đặt tên Controller là PostController để tương ứng với lớp Post.cs và tên bảng Post trong database, chọn lớp mô hình là Post (DammioEF.Models) và lớp data context là DammioEFEntities (DammioEF.Models). Về tạo Views, bạn tích hết các options để Visual Studio tự động tạo các view giao diện và nhấn Add.

Sau khi tạo xong, bạn chọn tập tin Views/Post/Index.cshtml, chuột phải chọn View in Browser (Google Chrome) để xem giao diện Web. Nếu bạn không thể làm cách này chỉ có thể chạy Debug dự án và đường dẫn http://localhost:xxxx/Post/Index.

Ở giao diện Web, bạn có thẻ thấy các mục tiêu đề ở các cột đều thay đổi khi bạn định nghĩa [DisplayName(“tên thuộc tính mới”)] cho từng thuộc tính ở lớp Post.cs. Đây là kiểu định nghĩa chú thích khá hay ho và mới mẻ ở Entity Framework. Thay vì trước kia bạn phải định nghĩa tên thay đổi trên giao diện thì bây giờ bạn có thể định nghĩa ở lớp Post.cs và tái sử dụng lớp này xuyên suốt dự án Web ở bất kỳ giao diện nào.

Định nghĩa thuộc tính xác nhận dữ liệu

Bạn có thể định nghĩa kiểu dữ liệu cho thuộc tính với các loại chú thích sau:

  • Timestamp: Thuộc tính này chỉ áp dụng cho kiểu dữ liệu mảng byte, dùng để tạo ra một cột dữ liệu thời gian trong database SQL. Entity Framework API tự động dùng cột này để kiểm tra đồng bộ với mệnh đề UPDATE trong database.
  • ConcurrencyCheck: Thuộc tính ConcurrencyCheck áp dụng cho một hay nhiều thuộc tính và các cột tương ứng trong database sẽ được kiểm tra đồng bộ thông qua mệnh đề Where.
  • Required: chỉ định thuộc tính phải có dữ liệu nhập vào trước khi submit về server.
  • MinLength: chiều dài tối thiểu của thuộc tính.
  • MaxLength: chiều đa tối thiểu của thuộc tính.
  • StringLength: định nghĩa chiều dài thuộc tính, cho phép đặc tả cả chiều dài tối thiểu và tối đa.
  • Range: định nghĩa giá trị số tối thiểu và tối đa của một thuộc tính.

Ví dụ thuộc tính Title ở lớp Post.cs phải có dữ liệu nhập vào, bạn hãy thêm [Required] vào như sau.

[Required]
[DisplayName("Tieu De")]  // Thuộc tính hiển thị
public string Title { get; set; }

Sau đó, bạn chạy giao diện Web (đường dẫn http://localhost:xxxx/Post/Create) hoặc tập tin , không nhập thông tin gì cả vào trường Title và nhấn Create, bạn sẽ hận báo lỗi như sau.

Ví dụ tiếp theo định nghĩa chiều dài chuỗi tối thiểu và tối đa của thuộc tính Title. Demo như ví dụ trước, bạn cũng nhận kết quả tương ứng là Title phải có chiều dài chuỗi tối thiểu là 10 và tối đa là 500.

[MinLength(10)]
[MaxLength(500)]
[DisplayName("Tieu De")]  // Thuộc tính hiển thị

Ví dụ tiếp theo, bạn định nghĩa thuộc tính Type (loại Post) có biên độ từ 1 đến 10.

[Range(1,10)]
[DisplayName("Loai")] // Thuộc tính hiển thị
public Nullable<int> Type { get; set; }

Định nghĩa thuộc tính mô hình

Các thuộc tính này chỉ nên dùng cho Code First.

Nếu bạn tạo dự án theo kiểu Code First, bạn bắt buộc phải dùng các chú thích thuộc tính để định nghĩa rõ thuộc tính nào là khóa chính, khóa ngoại,.. cũng như mối quan hệ giữa các lớp bảng trong database sẽ được gieo từ Code First.

  • Key: định nghĩa thuộc tính nào là khóa chính.
  • Table: bảng
  • Column: cột
  • Index: chỉ mục
  • ForeignKey: khóa ngoại
  • NotMapped: không ánh xạ (không kết nối)
  • InverseProperty: Thuộc tính đảo ngược, dùng để tạo quan hệ giữa các bảng 1-n hoặc n-n.

Ví dụ định nghĩa khóa chính và khóa ngoại ở lớp Post.cs như sau.

[Key]
public int PostId { get; set; }
[ForeignKey]
public int BlogId { get; set; }

Ngoài ra, còn nhiều kiểu định nghĩa thuộc tính chú thích khác mà bạn có thể tìm hiểu thêm trong các tài liệu của Microsoft hoặc trên Internet.

Kết luận

Chú thích dữ liệu (Data Annotation) trong Entity Framework giúp bạn định nghĩa dữ liệu thuộc tính trực tiếp trong mã nguồn được gieo từ các bảng cơ sở dữ liệu và giúp bạn kiểm soát được dữ liệu nhập vào từ người dùng tốt nhất cũng như cách định nghĩa dữ liệu hiển thị trên giao diện.

Bình luận Facebook

Để lại bình luận

avatar
1000
  Subscribe  
Notify of