Entity Framework Core kết nối với CSDL đã tồn tại trong MySQL

Kiến thức cần có:

  • Cơ sở dữ liệu
  • Lập trình hướng đối tượng với C#
  • Kết nối C# với CSDL MySQL
  • Hiểu về Entity Framework Core

Cài đặt CSDL

Để thực hiện bài mẫu này cần phải cài đặt Hệ quản trị CSDL MySQL.

Sau đó thực thi câu lệnh SQL theo liên kết sau: https://github.com/sinhdev/dotnet-core/blob/master/EFCoreMySql/OrderDB.sql 

Tạo dự án

  • Tạo dự án tên là "EFCoreMySql"
    dotnet new console -o EFCoreMySql
  • Thêm gói Entity Framework Core vào dự án
    cd ./EFCoreMySql
    dotnet add package MySql.EntityFrameworkCore
    dotnet add package Microsoft.EntityFrameworkCore.Design

Sử dụng lệnh "ef" để kết nối với CSDL đã tồn tại trong MySQL

  • Kiểm tra lệnh "ef" đã được cài đặt
    dotnet ef --help
  • Nếu chưa cài đặt thì thực hiện lệnh sau để cài đặt công cụ ef
    dotnet tool install --global dotnet-ef
  • Sử dụng lệnh DbContext Scaffold để tự động sinh ra model. Lệnh có hai đối số bắt buộc:
    • Một chuỗi kết nối phụ thuộc vào môi trường và nhà cung cấp cơ sở dữ liệu của bạn.
    • Đối số nhà cung cấp là nhà cung cấp Entity Framework cho cơ sở dữ liệu của bạn.
      dotnet ef dbcontext scaffold "server=localhost;user id=vtca;password=vtcacademy;port=3306;database=OrderDB;" MySql.EntityFrameworkCore -o Model
  • Khi bạn đã thực hiện lệnh, bạn sẽ thấy rằng một thư mục có tên Model đã được tạo trong thư mục dự án, chứa một tập hợp các tệp lớp đại diện cho các thực thể ngoài tệp cho lớp DbContext:
  • Tùy chọn -o (hoặc cách khác --output-dir) chỉ định thư mục nơi các tệp lớp sẽ được tạo. Nếu nó bị bỏ qua, các tệp lớp sẽ được tạo trong thư mục dự án (nơi chứa tệp .csproj).

  • Lớp DbContext sẽ lấy tên của cơ sở dữ liệu cộng với "Context", Bạn có thể ghi đè điều này bằng cách sử dụng tùy chọn -c hoặc --context, ví dụ:
    dotnet ef dbcontext scaffold "server=localhost;user id=vtca;password=vtcacademy;port=3306;database=OrderDB;" MySql.EntityFrameworkCore -o Model -c "OrderDBContext"

Chỉnh sửa Models

Nếu lệnh trên tạo phát sinh cảnh báo như sau:

Could not find type mapping for column 'OrderDB.Orders.order_date' with data type 'datetime'. Skipping column.

Chúng ta tiến hành sửa như sau:

  • Trong tệp Order.cs thêm Property tên là OrderDate vào lớp Order:
    public partial class Order
    {
        ...
        public DateTime OrderDate { get; set; }
        ...
    }
  • Trong tệp OrderDBContext.cs thêm ánh xạ thuộc tính OrderDate với cột order_date trong lớp OrderDBContext như sau:
    public partial class OrderDBContext : DbContext {
      protected override void OnModelCreating(ModelBuilder modelBuilder){
        ...
        modelBuilder.Entity<Order>(entity => {
          ...
          entity.Property(e => e.OrderDate).HasColumnName("order_date");
          ...
        });
        ...
      }
    }

Cấu hình Mô hình (Model)

Kết quả Mô hình được định cấu hình bằng API Fluent theo mặc định, đây là cách tiếp cận được khuyến nghị. Các cấu hình được đặt trong phương thức OnModelCreating của ngữ cảnh (context) đã tạo. Tuy nhiên, nếu thích sử dụng Chú thích dữ liệu để cấu hình, bạn có thể sử dụng lệnh chuyển -d hoặc --data-annotations: 

dotnet ef dbcontext scaffold "server=localhost;user id=vtca;password=vtcacademy;port=3306;database=OrderDB;ConvertZeroDateTime=true;" MySql.EntityFrameworkCore -d 

Vì Chú thích dữ liệu chỉ bao gồm một tập hợp con các tùy chọn cấu hình, bạn có thể thấy rằng API Fluent cũng đã được sử dụng để định cấu hình mô hình.

Cập nhật Mô hình

Cách tiếp cận được khuyến nghị để giữ các thay đổi đối với cơ sở dữ liệu đồng bộ với mô hình đã tạo là sử dụng chuyển đổi tức là để thực hiện các thay đổi đối với mô hình trước, sau đó sử dụng các công cụ để tạo mã truyền bá các sửa đổi cho cơ sở dữ liệu. Tuy nhiên, tùy thuộc vào hoàn cảnh của bạn, đây có thể không phải lúc nào cũng là một lựa chọn. Nếu bạn cần xây dựng lại mô hình sau khi các thay đổi lược đồ cơ sở dữ liệu đã được thực hiện, bạn có thể làm như vậy bằng cách chỉ định tùy chọn -f hoặc --force, ví dụ: 

dotnet ef dbcontext scaffold "server=localhost;user id=vtca;password=vtcacademy;port=3306;database=OrderDB;ConvertZeroDateTime=true;" MySql.EntityFrameworkCore --force

Tất cả các tệp lớp sẽ bị ghi đè, có nghĩa là bất kỳ sửa đổi nào mà bạn có thể đã thực hiện đối với chúng, ví dụ: thêm thuộc tính hoặc thành viên bổ sung, sẽ bị mất. Bạn có thể giảm thiểu điều này bằng cách chọn sử dụng API Fluent để cấu hình và sử dụng các lớp cấu hình riêng biệt. Ngoài ra, bạn có thể sử dụng các lớp từng phần để khai báo các thuộc tính bổ sung không ánh xạ tới các cột trong bảng cơ sở dữ liệu. 

Dịch chuyển

Khi mô hình đã được tạo trong các phiên bản trước của Entity Framework, có thể thêm một quá trình di chuyển không ảnh hưởng đến lược đồ của cơ sở dữ liệu hiện có bằng cách sử dụng tùy chọn -ignorechanges. Tùy chọn này không tồn tại trong Entity Framework Core, do đó, cách giải quyết là tạo lần di chuyển đầu tiên và sau đó xóa hoặc nhận xét nội dung của phương thức Up trước khi áp dụng quá trình di chuyển vào cơ sở dữ liệu. Điều này sẽ dẫn đến một mô hình và một lược đồ cơ sở dữ liệu khớp với nhau.

Chạy thử dự án xem có ánh xạ được với CSDL

Trong file Program.cs thực hiện mã lệnh như sau:

using System;
using EFCoreDemo.Models;

namespace EFCoreDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using(var context = new OrderDBContext()){
                Item item = new Item();
                item.ItemName = "New item EF";
                item.Amount = 7;
                item.ItemDescription = "des";
                item.ItemStatus = 1;
                item.UnitPrice = 100;

                context.Items.Add(item);
                context.SaveChanges();
            }
        }
    }
}

Mã lệnh này sẽ thực hiện thao tác thêm 1 Item mới vào trong CSDL.