Cách thêm view vào DbContext trong Entity Framework Core

Làm việc với cơ sở dữ liệu là một nhiệm vụ thú vị nhưng đầy thử thách. Khi ứng dụng của chúng ta phát triển, chúng ta nhận thấy các cơ hội để tối ưu hóa cơ sở mã của mình cùng với hiệu suất truy vấn.

View là một cách tuyệt vời để đạt được cả hai mục tiêu. Với Entity Framework Core 5 (EF Core), việc tận dụng tất cả các công cụ mà cơ sở dữ liệu của chúng ta cung cấp chưa bao giờ đơn giản hơn.

Bài viết này sẽ hướng dẫn cách tạo một chuyển đổi (migrate) cơ sở dữ liệu trống, định nghĩa một view phức tạp trong SQLite, sau đó sửa đổi DbContext EF Core để cung cấp cho chúng ta quyền truy cập vào view. Bắt đầu nào!

View trong SQL là gì?

Dành cho những người chưa biết, view là một bảng ảo dựa trên tập hợp kết quả của một truy vấn được định nghĩa trước. View cho phép chúng ta đóng gói một truy vấn phức tạp vào một thực thể logic trong cơ sở dữ liệu của chúng ta.

Việc tận dụng view có thể giúp đơn giản hóa các truy vấn và có thể giúp cải thiện hiệu suất cơ sở dữ liệu. Mỗi công cụ cơ sở dữ liệu sẽ triển khai view khác nhau, vì vậy hãy tham khảo tài liệu của nhà cung cấp cơ sở.

View trong SQL Server | Comdy
Cách quản lý view trong SQL Server như tạo view mới, xóa view và cập nhật dữ liệu của các bảng bên dưới thông qua view.

Mô hình dữ liệu làm việc

Chúng ta sẽ làm việc với mô hình dữ liệu về Giải trí. Trong DbContext định nghĩa các bảng như Productions Ratings, nhưng không quá quan trọng đối với bài viết này.

Để dễ hình dung, dưới đây là hai bảng được định nghĩa trong C#. Bài viết này giả định bạn có hiểu biết cơ bản về ngữ cảnh dữ liệu EF Core và cách chúng ánh xạ tới cơ sở dữ liệu.

public abstract class Production
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Release { get; set; }

    public List<Character> Characters { get; set; } = new List<Character>();
    public List<Rating> Ratings { get; set; } = new List<Rating>();
}

public class Rating
{
    public int Id { get; set; }
    public int ProductionId { get; set; }
    public Production Production { get; set; }
    public string Source { get; set; }
    public int Stars { get; set; }
}

Mục tiêu của chúng ta là tạo view trong SQL có thể giảm độ phức tạp của câu lệnh LINQ sau đây.

var highestRated = database
    .Productions
    .Select(x => new
    {
        id = x.Id,
        name = x.Name,
        avg = x.Ratings.Average(r => r.Stars)
    })
    .OrderByDescending(x => x.avg);

Thêm chuyển đổi trống

Trước tiên, chúng ta cần tạo một chuyển đổi để thêm định nghĩa view vào cơ sở dữ liệu của chúng ta. Chúng ta có thể thêm một lần chuyển đổi trống bằng cách yêu cầu Entity Framework Core CLI thêm một lần chuyển đổi mới, miễn là chưa có thay đổi mô hình nổi bật nào được áp dụng.

Tôi nhận thấy rằng bất kỳ dữ liệu mẫu nào trong DbContext đều gây khó khăn cho việc tạo chuyển đổi trống.

 dotnet ef migrations add ProductionRatingAveragesView

Khi EF Core tạo chuyển đổi bổ sung, chúng ta sẽ có mã sau được tạo trong thư mục Migrations. Namespace sẽ khác nhau dựa trên dự án của bạn.

using Microsoft.EntityFrameworkCore.Migrations;

namespace Entertainment.Migrations
{
    public partial class ProductionRatingAveragesView : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {

        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {

        }
    }
}

Chuyển đổi view SQLite

Chúng ta đang làm việc với miền về giải trí có tham chiếu đến Productions Ratings. Thay vì viết các biểu thức LINQ phức tạp hoặc các câu lệnh SQL thô mỗi khi chúng ta cần xếp hạng trung bình, chúng ta hãy thử làm theo cách khác xem sao.

Trong trường hợp này, chúng ta sẽ sử dụng view trong SQLite và tạo một view mới có tên ProductionRatingAverages.

create view ProductionRatingAverages as
select p.Id, 
    p.Name, 
    avg(r.Stars) as AverageStarRating
from Productions p 
inner join Ratings r on p.Id = R.ProductionId
group by p.Id, p.Name;

Chúng ta sẽ muốn thêm tập lệnh tạo view SQL này vào tệp chuyển đổi trống ProductionRatingAveragesView của chúng ta bằng cách sửa đổi phương thức Up.

Chúng ta cũng muốn xóa view nếu chúng ta quyết định hoàn nguyên quá trình chuyển đổi; chúng ta có thể đảm bảo hành vi này bằng cách thay đổi phương thức Down.

using Microsoft.EntityFrameworkCore.Migrations;

namespace Entertainment.Migrations
{
    public partial class ProductionRatingAveragesView : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql(@"
create view ProductionRatingAverages as
select p.Id, p.Name, avg(r.Stars) as AverageStarRating
from Productions p inner join Ratings r on p.Id = R.ProductionId
group by p.Id, p.Name;
");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql(@"
drop view ProductionRatingAverages;
");
        }
    }
}

Tôi thích sử dụng ký tự @ khi thêm các ký tự SQL và dòng mới vào tệp C#. Tôi thấy định dạng này dễ đọc hơn nhiều, mặc dù nó có vẻ lạ.

Tôi cũng muốn giới thiệu cách lưu trữ mã SQL trong các tập tin bên ngoài khi làm việc với EF Core. Các nhà phát triển có thể bị cám dỗ để thay đổi các tệp đó hơn là tạo một quá trình chuyển đổi mới.

Thay đổi cách chuyển đổi sẽ chỉ dẫn đến các vấn đề đau đầu sau này. Hãy nhớ rằng, quá trình chuyển đổi là tạm thời và sau khi áp dụng sẽ bị khóa.

Bước tiếp theo là thêm mô hình  ProductionAverage mới vào DbContext của chúng ta, mô hình này quen thuộc với bất kỳ người dùng EF Core nào.

Định nghĩa mô hình DbContext

Vì chúng ta đã tạo view, chúng ta có thể tạo một mô hình bắt chước các cột của tập kết quả của view trả về. Chúng ta có các thuộc tính là Id, Name AverageStarRating.

public class ProductionRatingAverage
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double AverageStarRating { get; set; }
}

Tiếp theo, hãy thêm một thuộc tính DbSet vào DbContext của chúng ta như sau.

public DbSet<ProductionRatingAverage> ProductionRatingAverages { get; set; }

Cuối cùng, hãy ánh xạ thực thể của chúng ta với view trong phương thức DbContext.OnModelCreating.

modelBuilder
    .Entity<ProductionRatingAverage>()
    .ToView(nameof(ProductionRatingAverages))
    .HasKey(t => t.Id);

Chúng ta có thể sử dụng nameof vì tên của thuộc tính DbSet của chúng ta khớp với tên view, nhưng phương thức này cũng chấp nhận bất kỳ giá trị chuỗi tùy ý nào. Việc hỗ trợ các giá trị chuỗi có thể hữu ích khi quy ước đặt tên cơ sở dữ liệu của chúng ta khác với quy ước đặt tên trong C#.

Gọi view của chúng ta từ C#

Cuối cùng, chúng ta có thể sử dụng view mới giống như chúng ta làm với bất kỳ thực thể nào khác.

var database = new EntertainmentDbContext();

var averages = 
    await database
        .ProductionRatingAverages
        .ToListAsync();

Hãy lưu ý rằng danh sách này là một view và bất kỳ nỗ lực cập nhật bất kỳ dữ liệu nào đều có thể không thành công. Một số cơ sở dữ liệu SQL hỗ trợ view đọc / ghi, nhưng chỉ khi chúng ta định nghĩa view với một bảng tham chiếu.

Phần kết luận

Với EF Core 5, chúng ta có thể thêm view vào trong DbContext và tạo view trong database bằng cách sử dụng cơ chế chuyển đổi cơ sở dữ liệu tích hợp sẵn.

Các mô hình hoạt động như khi chúng được ánh xạ trực tiếp vào một bảng để tận dụng các quy ước ánh xạ mặc định. Trong phương thức OnModelCreating, chúng ta có thể xác định khóa chính, ánh xạ cột và nhiều thứ khác của view nếu các quy ước đặt tên khác nhau.

Tôi hy vọng bạn thấy bài viết này hữu ích và vui lòng để lại nhận xét về cách view SQL đã giúp bạn giải quyết một vấn đề khó khăn.

Nếu Comdy hữu ích và giúp bạn tiết kiệm thời gian làm việc

Bạn có thể vui lòng đưa Comdy vào whitelist của trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi trong việc trả tiền cho dịch vụ lưu trữ web để duy trì hoạt động của trang web.

Entity Framework Core
Bài Viết Liên Quan:
Bộ chuyển đổi giá trị của Entity Framework Core 5
Trung Nguyen 12/11/2021
Bộ chuyển đổi giá trị của Entity Framework Core 5

Bài viết này sẽ giúp bạn tìm hiểu về bộ chuyển đổi giá trị - một trong những cải tiến mạnh mẽ của Entity Framework Core 5.

Truy vấn SQL thô với Entity Framework Core 5
Trung Nguyen 11/11/2021
Truy vấn SQL thô với Entity Framework Core 5

Trong bài viết này, chúng ta sẽ khám phá cách làm việc với các tính năng của Entity Framework Core 5 (EF Core) để thực thi truy vấn SQL thô.

Mô hình hóa các mối quan hệ SQL trong EF Core
Trung Nguyen 03/11/2021
Mô hình hóa các mối quan hệ SQL trong EF Core

Bài viết này sẽ khám phá các mối quan hệ trong cơ sở dữ liệu quan hệ và cách mô hình hóa các mối quan hệ đó bằng cách tiếp cận Code First trong EF Core.

Dữ liệu đệ quy với Entity Framework Core và SQL Server
Trung Nguyen 01/11/2021
Dữ liệu đệ quy với Entity Framework Core và SQL Server

Trong bài viết này, chúng ta sẽ khám phá cách lập mô hình dữ liệu đệ quy với Entity Framework Core và SQL Server