C# Cơ bản .NET Core §1) Cài đặt, chương trình C# đầu tiên §2) Biến, kiểu dữ liệu và nhập/xuất §3) Toán tử số học và gán §4) So sánh, logic và lệnh if, switch §5) Vòng lặp for, while §6) Phương thức - Method §7) Phương thức - Delegate §8) Lớp - Class §9) Kiểu vô danh và dynamic §10) Biểu thức lambda §11) Event §12) Hàm hủy - Quá tải toán tử - thành viên tĩnh - indexer §13) Lớp lồng nhau - namespace §14) null và nullable §15) Mảng §16) Chuỗi ký tự §17) Tính kế thừa §18) Tính đa hình - abstract - interface §19) Struct và Enum §20) Ngoại lệ Exeption §21) IDisposable - using §22) File cơ bản §23) FileStream §24) Generic §25) Collection - List §26) SortedList §27) Queue / Stack §28) Linkedlist §29) Dictionary - HashSet §30) Phương thức mở rộng §31) ObservableCollection §32) LINQ §33) (Multithreading) async - bất đồng bộ §34) Type §35) Attribute Annotation §36) DI Dependency Injection §37) (Multithreading) Parallel §38) (Networking) HttpClient §39) (Networking) HttpMessageHandler §40) (Networking) HttpListener §41) (Networking) Tcp TcpListenerr/TcpClient §42) (ADO.NET) SqlConnection §43) (ADO.NET) SqlCommand §44) (EF Core) Tổng quan §45) (EF Core) Tạo Model §46) (EF Core) Fluent API §47) (EF Core) Query §48) (EF Core) Scaffold §49) (EF Core) Migration §50) (ASP.NET CORE) Hello World! §51) (ASP.NET CORE) Middleware §52) (ASP.NET CORE) Map - Request - Response §53) (ASP.NET CORE) IServiceCollection - MapWhen §54) (ASP.NET CORE) Session - ISession §55) (ASP.NET CORE) Configuration §56) (ASP.NET CORE MVC) Controller - View

Giới thiệu Fluent API

Fluent API cũng là phương pháp để tạo ra các bảng - bên cạnh phương pháp sử dụng Data Annotation đã biết. Để sử dụng Fluent API, cần nạp chồng phương thức OnModelCreating của lớp DbContext, rồi tại đây sử dụng các API thích hợp. Dùng đến API nếu các Attribute chưa đủ dùng để thực hiện các thiết lập phức tạp.

Tiếp tục thực hiện trên ví dụ Tạo Model, thêm phương thức OnModelCreating vào lớp ShopContext

public class ShopContext : DbContext
{
    /..
    override protected void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);

        // Các Fluent API

    }
    /..
}

Phương thức này thi hành khi EnsureCreatedAsync chạy. Trong phương thức này nhận được một đối tượng kiểu ModelBuilder, từ đối tượng này, thực hiện phương thức Entity để lấy đối tượng cụ thể cần tác động, thông qua kiểu EntityTypeBuilder<TEntity> trả về.

Ví dụ, cần lấy EntityTypeBuilder<Product> cho bảng Product

public class ShopContext : DbContext
{
    /..
    override protected void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Product>(entity => {

            // entity là đối tượng kiểu EntityTypeBuilder
            // từ entity thực hiện các tác động đển bảng Product!

        });

    }
    /..
}

Sau đây sử dụng một số tác vụ với Fluent API. Hãy copy lại mã nguồn ví dụ trước, đổi lại là EF03, để tiếp thực hành EF02

PropertyBuilder<TProperty> - thiết lập thuộc tính

Đối tượng kiểu PropertyBuilder<TProperty> để thiết lập các thuộc tính của bảng. Một vài phương thức là:

  • ValueGeneratedNever() thuộc tính thiết lập giá trị không tự phát sinh bởi database. Dùng nó yêu cầu database không tự phát sinh giá trị mặc định khi dòng mới chèn vào. Tương đương với thuộc tính [DatabaseGenerated(DatabaseGeneratedOption.None)]
    modelBuilder.Entity<Product>(entity => {
    
            entity
                .Property(pro => pro.Name)
                .ValueGeneratedNever();
    
        });
    
  • ValueGeneratedOnAdd database tự phát sinh giá trị khi dòng mới chèn vào
  • HasDefaultValueSql thiết lập giá trị mặc định của cột, sinh ra bởi DB
    entity.Property(pro => pro.Price)
          .ValueGeneratedNever().HasDefaultValueSql("((0))");
    

HasOne và HasMany

Phương thức này để thiết lập đầu thứ nhất của quan hệ 1 - 1 hoặc 1 - nhiều. Ngay sau khi gọi phương thức này cần gọi WithOne() hoặc WithMany() để thiết lập đầu kia, ngoài ra cũng có thể gọi ngay OnDelete() để thiết lập ứng xử khi xóa, nếu muốn đặt tên ràng buộc này thì gọi HasConstraintName, nếu muốn thiết lập FK thì là HasForeignKey ...

Ví dụ, tạo thêm lớp User

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ef02.Model
{
    public class User
    {
        [Key]
        public int UserId {set; get;}

        [StringLength(20)]
        public string UserName {set; get;}

        public List<Product> ProductsPost {set; get;}  // Các sản phẩm do User đăng
    }
}

Đưa lớp này vào ShopContext, bằng cách thêm

public DbSet<User> users {set; get;}

Cập nhật thêm vào Product

namespace ef02.Model
{
    [Table("Products")]
    public class Product
    {
        /...

        public int? UserPostId {set;  get;}     // Lưu thông tin người Post sản phẩm
        public User UserPost {set; get;}

    }
}

Như vậy, có thể thiết lập - mỗi sản phẩm do một người đăng - một người đăng nhiều sản phẩm.

/..
modelBuilder.Entity<Product>(entity => {

     entity .HasOne(e => e.UserPost)                     // Chỉ ra phía một
            .WithMany(user => user.ProductsPost)         // Chỉ ra phía nhiều
            .HasForeignKey("UserPostId")                 // Chỉ ra tên FK
            .OnDelete(DeleteBehavior.SetNull)            // Ứng xử khi User bị xóa
            .HasConstraintName("FK_Products_user_post"); // Tự đặt tên Constrain

});
/..

Tương tự với HasMany thiết lập chiều nhiều trước trong quan hệ nhiều - một hoặc nhiều - nhiều.

HasIndex và IsUnique

HasIndex để tạo ra Index, tham là một cột hoặc các cột, nếu muốn Index này là giá trị không được trùng lặp thì gọi thêm IsUnique

/..
  entity.HasIndex(p => p.Name)              // cột đánh index
        .IsUnique()                         // ràng buộc duy nhất
        .HasName("index_name_product");     // đặt tên index
/..

Nếu muốn đánh index nhiều cột thì

entity.HasIndex(p => new {p.fiel1, p.fiel2 ...}) ...
Source Code (EF03)
Đăng ký theo dõi ủng hộ kênh