Khởi tạo dự án Hello World với ADO.NET và Entity Framework
- 19-11-2024
- Toanngo92
- 0 Comments
3.1 Tổng quan về ADO.NET
Các ứng dụng ASP.NET thường sử dụng dữ liệu dưới nhiều cách khác nhau. Có nhiều phương pháp mà các nhà phát triển có thể sử dụng để làm việc với dữ liệu trong các ứng dụng Web. Một trong số đó là ADO.NET.
ADO.NET là một thành phần cốt lõi của framework .NET và được sử dụng để thiết lập kết nối giữa một ứng dụng và các nguồn dữ liệu. Trong Microsoft.NET framework, ADO.NET cung cấp một cầu nối giữa một loạt các hệ thống cơ sở dữ liệu thông qua một bộ các thành phần chuẩn. Nó có thể được tìm thấy trong thư viện lớp cơ sở chuẩn đi kèm với Microsoft.NET framework.
ADO.NET đôi khi được gọi là một sự phát triển của công nghệ ActiveX Data Objects (ADO), vốn rất thành công trong những ngày đầu của Microsoft.
3.2 Tầng Dữ liệu
Bất kỳ ứng dụng nào được phát triển đều có một kiến trúc và cần có các tầng (layers) sau:
- Tầng mà người dùng tương tác: Đây là khu vực trực tiếp hiển thị và có thể truy cập với người dùng.
- Tầng mà các xác thực/giới hạn được định nghĩa: Ở đây, các quy tắc và hạn chế cho dữ liệu được áp dụng.
- Tầng trong đó dữ liệu được lưu trữ: Đây là nơi lưu trữ dữ liệu thực tế.
Microsoft đã cung cấp một giải pháp cho tầng dữ liệu. Quá trình phát triển các tầng dữ liệu được hiển thị trong Hình 3.1. Nó bắt đầu với Data Access Objects (DAO) và bây giờ là Entity Framework (EF).
3.2.1 Đối tượng Truy cập Dữ liệu (DAO)
Trong những ngày đầu của .NET, đặc biệt là trong Visual Basic (VB), DAO rất phổ biến như là một giao diện hướng đối tượng được ánh xạ đến công cụ cơ sở dữ liệu của Microsoft. Các nhà phát triển VB có thể sử dụng Open Database Connectivity (ODBC) để kết nối trực tiếp với các bảng của Access và các cơ sở dữ liệu khác. Nó phù hợp nhất cho các máy độc lập.
3.2.2 Đối tượng Dữ liệu Từ xa (RDO)
RDO là một giao diện truy cập dữ liệu hướng đối tượng kết hợp khả năng đơn giản của DAO với công suất thấp và sự linh hoạt của ODBC. Đây là một bước tiến quan trọng trong việc tách riêng dữ liệu khỏi các đặc tính, phương thức và đối tượng. Nó làm cho các phần phức tạp của các thao tác ghi và các tập hợp kết quả phức tạp trở nên dễ xử lý hơn.
3.2.3 Đối tượng Dữ liệu Chủ động (ADO)
Mặc dù ADO dường như là sự kế thừa của DAO/RDO, nó thực sự là một giao diện lập trình ứng dụng cho phép các nhà phát triển tạo ra các chương trình Windows có thể kết nối với một loạt các cơ sở dữ liệu. ADO cung cấp một khả năng cho phép các ứng dụng có thể truy cập dữ liệu được lưu trữ trong một cách tổng quát mà không yêu cầu cụ thể về thực hiện triển khai cơ sở dữ liệu.
Điều này làm cho việc sử dụng trở nên dễ dàng hơn cho những ai không quen với các thao tác cơ sở dữ liệu phức tạp. ADO là một gói phần mềm tích hợp các chức năng của DAO và RDO thành một giao diện duy nhất.
3.2.4 ADO.NET
Khi XML trở nên phổ biến và là một công nghệ nổi lên, ADO.NET đã phát triển để hỗ trợ XML. Nó cho phép truy cập dữ liệu từ nhiều nguồn khác nhau như Microsoft SQL Server, Oracle, Sybase, MySQL và OLE DB thông qua các bộ điều hợp dữ liệu. ADO.NET là một tập hợp các lớp được đặt trong thư viện cơ sở, System.Data.dll
.
Nó bao gồm một số lượng lớn các thành phần giúp nhà phát triển có thể xây dựng các ứng dụng doanh nghiệp phân tán. Có hai thành phần chính của ADO.NET, đó là truy cập dữ liệu và quản lý dữ liệu, mỗi thành phần cung cấp bảng dữ liệu và tập dữ liệu như hiển thị trong Hình 3.2.
Trong ADO.NET, các thành phần sau đây cho phép các nhà phát triển đọc và ghi dữ liệu từ các nguồn dữ liệu:
- Connection
Đối tượng này có trách nhiệm cung cấp khả năng kết nối với một nguồn dữ liệu. LớpSqlConnection
trong thư viện ADO.NET là một ví dụ của lớp đại diện cho một kết nối. - Command
Đối tượng này cung cấp quyền truy cập vào các lệnh cơ sở dữ liệu. Những lệnh này được sử dụng để truy xuất, sửa đổi hoặc thực thi các câu lệnh SQL. Ví dụ, lớpSqlCommand
có phương thứcExecuteScalar()
được sử dụng để trả về một giá trị duy nhất từ cơ sở dữ liệu. - DataAdapter
Đối tượng này hoạt động như một cầu nối giữa đối tượngDataSet
và nguồn dữ liệu. LớpDataAdapter
sử dụng các đối tượngCommand
để thực thi các lệnh SQL trên nguồn dữ liệu nhằm tải dữ liệu vàoDataSet
và ghi lại những thay đổi được thực hiện trongDataSet
trở lại nguồn dữ liệu. Ví dụ, lớpSqlDataAdapter
chứa một phương thức được gọi làFill
giúp truyền dữ liệu vào các đối tượng của lớpDataTable
. - DataReader
Đối tượngDataReader
cung cấp một luồng dữ liệu hiệu suất cao từ nguồn dữ liệu. Ví dụ, lớpSqlDataReader
được sử dụng để giữ dữ liệu trả về bởi phương thứcExecuteReader()
của lớpSqlCommand
.SqlDataReader
được sử dụng để lưu trữ dữ liệu.
3.3 Entity Framework (EF)
Entity Framework là một hệ quản trị cơ sở dữ liệu dựa trên ánh xạ đối tượng-quan hệ (ORM). Đây là một phiên bản cải tiến của ADO.NET, cung cấp cho lập trình viên một giao diện cơ sở dữ liệu hoàn toàn tự động.
Trước phiên bản .NET 3.5, các nhà phát triển thường phải viết mã ADO.NET để lưu trữ hoặc truy xuất dữ liệu ứng dụng từ cơ sở dữ liệu. Họ sử dụng một phương pháp truyền thống để truy cập cơ sở dữ liệu bao gồm khởi tạo một kết nối, sau đó tạo một tập hợp kết quả hoặc một tập dữ liệu để truy xuất hoặc lưu trữ dữ liệu vào cơ sở dữ liệu. Bước tiếp theo là chuyển đổi dữ liệu từ tập dữ liệu sang các đối tượng .NET và áp dụng các quy tắc nghiệp vụ theo yêu cầu của ứng dụng doanh nghiệp. Đây là một quá trình tốn nhiều thời gian.
Entity Framework (EF) lần đầu tiên được tích hợp trong Visual Studio 2008 SP1 và .NET Framework 3.5 SP1. Từ đó đến nay, EF đã phát triển mạnh mẽ. Hiện nay, các phiên bản EF 6.0 và EF Core đang được sử dụng.
Trong EF, ngôn ngữ Language Integrated Query (LINQ) được sử dụng để truy cập và tương tác với dữ liệu bằng cách sử dụng mã tự động tạo sẵn. Lợi ích chính của mã tự động tạo sẵn là nó giảm bớt thời gian phát triển cho nhiều tầng, như tầng Model và tầng Truy cập Dữ liệu (Data Access Layer).
Sự tương tác giữa EF với lớp miền (domain class) và cơ sở dữ liệu được thể hiện trong Hình 3.3.
EF thiết lập một cầu nối giữa các thực thể nghiệp vụ và các bảng dữ liệu. Nó lưu trữ dữ liệu được lưu trong các thuộc tính của các thực thể nghiệp vụ. Nó cũng truy xuất dữ liệu từ cơ sở dữ liệu và tự động chuyển đổi dữ liệu này thành các thực thể nghiệp vụ bằng mã của EF. EF thực thi các truy vấn cơ sở dữ liệu và sau đó chuyển đổi kết quả thành các thực thể đối tượng miền có thể được sử dụng trong ứng dụng.
Bảng 3.1 hiển thị các phiên bản khác nhau của Entity Framework.
Version | Release Date | Description |
---|---|---|
EF 1.0 | 11 August 2008 | Bao gồm trong .NET Framework 3.5 SP1 và Visual Studio 2008 SP1. Bị chỉ trích do nhiều vấn đề. |
EF 4.0 | 12 April 2010 | Phát hành với .NET 4.0, khắc phục các vấn đề từ phiên bản trước. |
EF 4.1 | 12 April 2011 | Phát hành với hỗ trợ Code First. |
EF 4.1 Update 1 | 25 July 2011 | Sửa lỗi và hỗ trợ các kiểu mới. |
EF 4.3.1 | 29 February 2012 | Thêm hỗ trợ cho di trú dữ liệu (migration). |
EF 5.0 | 11 August 2012 | Dành cho .NET Framework 4.5, có sẵn cho .NET 4.0. |
EF 6.0 | 17 October 2013 | Dự án mã nguồn mở, cải tiến hỗ trợ Code First. |
EF Core 1.0 | 27 June 2016 | Viết lại hoàn chỉnh, hỗ trợ đa nền tảng, giấy phép mã nguồn mở (Giấy phép Apache 2.0). |
EF Core 2.0 | 14 August 2017 | Phát hành cùng với Visual Studio 2017 15.3 và ASP.NET Core 2.0. |
EF Core 3.0 | 23 September 2019 | Phát hành với Visual Studio 2019 16.3 và ASP.NET Core 3.0. |
EF Core 3.1 | 3 December 2019 | Phát hành chính thức, là phiên bản hỗ trợ dài hạn ít nhất đến 3 December 2022. |
EF Core 5.0 | 10 November 2020 | Phát hành cho sản xuất. |
EF Core 6.0 | 10 November 2021 | Phiên bản hỗ trợ dài hạn ít nhất đến 12 November 2024. |
EF Core 7.0 | 8 November 2022 | Phát hành với các tính năng mới như cột và cập nhật hàng loạt. |
EF Core 8.0 | 14 November 2023 | Cho phép sử dụng các đối tượng giá trị (Value Objects) bằng cách sử dụng các bộ sưu tập phức tạp và nguyên thủy. |
3.3.1 Các Tính năng và Lợi ích của Entity Framework (EF)
EF là một ORM trong đó trọng tâm chính là giảm tải khối lượng công việc phát triển và tăng năng suất bằng cách giảm thiểu các công việc lặp lại không cần thiết khi tương tác với dữ liệu trong các ứng dụng.
Các tính năng của EF bao gồm:
- EF sử dụng các truy vấn LINQ thay vì các truy vấn SQL, sau đó được chuyển đổi thành truy vấn cụ thể cho cơ sở dữ liệu. Nó xử lý các truy vấn theo thủ tục và tham số hóa.
- EF cho phép lưu vào bộ nhớ đệm để các truy vấn có thể được trả lời từ bộ đệm trong trường hợp có các truy vấn lặp lại.
- EF cho phép xử lý đồng thời và đảm bảo rằng bất kỳ thay đổi nào đang được ghi đè sẽ được kiểm tra bởi một người dùng khác.
- EF xây dựng mô hình thực thể miền (EDM). Mô hình này dựa trên đối tượng CLR dạng Plain Old CLR Object (POCO) và được sử dụng để truy vấn và lưu dữ liệu. POCO là một lớp độc lập với bất kỳ framework nào. POCO là đối tượng nghiệp vụ và có tính logic nghiệp vụ của ứng dụng.
- EF tự động xử lý quản lý giao dịch khi yêu cầu hoặc lưu dữ liệu.
- EF tạo ra các lệnh cơ sở dữ liệu cần thiết cho các thao tác Tạo, Đọc, Cập nhật, và Xóa (CRUD) và sau đó thực thi chúng.
3.4 Quy trình làm việc của EF và EF Core
EF và EF Core có một tầng ánh xạ giữa các lớp miền và schema. Nó có thể được triển khai bằng một trong ba phương pháp tiếp cận sau đây:
- Phương pháp Tiếp cận Cơ sở dữ liệu Trước (Database-First Approach)
- Phương pháp Tiếp cận Code-First (Code-First Approach)
- Phương pháp Tiếp cận Mô hình Trước (Model-First Approach)
- Phương pháp Tiếp cận Cơ sở dữ liệu Trước (Database-First Approach)
Trong phương pháp tiếp cận cơ sở dữ liệu trước, bước đầu tiên là tạo một cơ sở dữ liệu với tất cả các bảng và thủ tục. EDM tự động tạo các miền. Phương pháp này tập trung vào việc thiết kế cơ sở dữ liệu.- Ưu điểm:
- Các cơ sở dữ liệu hiện có có thể được sử dụng để phát triển.
- Quá trình phát triển trở nên dễ dàng hơn vì các lớp được tạo tự động.
- Schema cơ sở dữ liệu được xác định rõ ràng.
- Ưu điểm:
- Phương pháp Tiếp cận Code-First (Code-First Approach)
Trong phương pháp tiếp cận code-first, các lớp miền được tạo ra trước, sau đó trình hướng dẫn của EF tạo các bảng cơ sở dữ liệu dựa trên mã.- Ưu điểm:
- Đồng bộ hóa cơ sở dữ liệu là dễ dàng cho các môi trường sử dụng di trú EF.
- Phương pháp này cung cấp tính linh hoạt đầy đủ và kiểm soát mã.
- Ưu điểm:
- Phương pháp Tiếp cận Mô hình Trước (Model-First Approach)
Trong phương pháp tiếp cận mô hình trước, nhà phát triển thiết kế các thực thể và các mối quan hệ trên nền tảng EDMX. Sau đó, thông qua trình hướng dẫn của EF, các lựa chọn của người dùng được tạo ra.
Phương pháp Tiếp cận Mô hình Trước (Model-First Approach) cung cấp ưu điểm trong việc tạo mô hình dễ dàng cho nhà thiết kế, các lớp miền và cơ sở dữ liệu được tự động tạo ra. Phương pháp này có lợi trong kiến trúc doanh nghiệp.
- Ưu điểm:
- Cách tiếp cận thân thiện với nhà thiết kế UML.
- Yêu cầu ít tiếp xúc với lập trình.
Tuy nhiên, trong phương pháp mô hình trước, cấu trúc được xử lý tự động nên có ít quyền kiểm soát đối với cơ sở dữ liệu và mã.
3.5 Xử lý Dữ liệu trong ASP.NET MVC với Cơ sở dữ liệu Code-first
Để tạo ứng dụng thông qua phương pháp code-first trong ASP.NET Core MVC, thực hiện các bước sau:
Mở Visual Studio 2022. Để tạo một dự án mới, chọn tùy chọn Create a new project như được hiển thị trong Hình 3.4.
Một cửa sổ Create a new project sẽ được hiển thị.
Để tạo một ứng dụng web, chọn tùy chọn ASP.NET Core Web App (Model-View-Controller) và sau đó nhấp vào Next như hiển thị trong Hình 3.5.
Trong cửa sổ Configure your new project, thêm tên dự án là MyCodeFirstApproachDemo và chọn vị trí để lưu dự án như được hiển thị trong Hình 3.6.
Trong cửa sổ Additional information, chọn .NET 8.0 (Long Term Support) và nhấn Create như được hiển thị trong Hình 3.7.
Trong Solution Explorer, lưu ý các tệp và thư mục được tạo ra.
Chọn Dependencies. Xem Hình 3.8.
Nhấp chuột phải vào Dependencies và chọn Manage NuGet Packages. Trình quản lý NuGet sẽ được hiển thị.
Để cài đặt nhà cung cấp EF SQL Server, tìm kiếm Microsoft.EntityFrameworkCore.SqlServer và sau đó nhấp vào Install như hiển thị trong Hình 3.9.
Chấp nhận thỏa thuận cấp phép. Nhà cung cấp sẽ được cài đặt.
Tiếp theo, tìm kiếm Microsoft.EntityFrameworkCore.Tools và sau đó nhấp vào Install như hiển thị trong Hình 3.10.
Chấp nhận thỏa thuận cấp phép. Các công cụ sẽ được cài đặt.
Lưu ý: Điều quan trọng là phải chọn phiên bản của cả hai gói này tương thích với phiên bản .NET Core của bạn.
Để thêm một lớp, từ Solution Explorer, chọn thư mục Models, nhấp chuột phải, và từ menu phím tắt, chọn Add → Class như hiển thị trong Hình 3.11.
Để tạo một lớp có tên là Customer, thay đổi tên lớp mặc định thành Customer và sau đó nhấn Add như hiển thị trong Hình 3.12.
Mẫu tự động tạo mặc định cho lớp được hiển thị trong Hình 3.13.
Thêm get set cho lớp:
public class Customer {
public int Id { get; set; }
public string CustName { get; set; }
public bool IsMarried { get; set; }
}
Bước tiếp theo là thêm ngữ cảnh cơ sở dữ liệu (database context). Chọn thư mục Models từ Solution Explorer và chọn Add > Class. Nhập một tên cho context (bối cảnh). Trong trường hợp này, tên CustomerContext được thêm vào, như được hiển thị trong Hình 3.14.
Sửa đổi lớp tự động tạo và thêm mã theo mã dưới:
using Microsoft.EntityFrameworkCore;
public class CustomerContext : DbContext {
public CustomerContext(DbContextOptions<CustomerContext> options) : base(options) { }
public DbSet<Customer> Customer { get; set; }
}
Trong khi chỉnh sửa mẫu lớp mặc định cho ngữ cảnh (context), cần lưu ý các điểm sau:
- Kế thừa một lớp từ DbContext, được cung cấp bởi Microsoft.EntityFrameworkCore.
- Cung cấp một cấu trúc khởi tạo được kế thừa từ lớp cơ sở.
- Một hàm dựa trên lớp trả về đối tượng lớp DbSet.
Tiếp theo, cần cung cấp chuỗi kết nối (connection string) cho cơ sở dữ liệu. Cấu hình tệp appsettings.json để cung cấp chuỗi kết nối như được hiển thị trong Hình 3.15.
Đoạn mã dưới hiển thị mã cấu hình. Lưu ý rằng tên của máy chủ là [DESKTOP-OMPTY7T\SQLEXPRESS]. Bạn có thể thay đổi tên theo cấu hình cục bộ. Tên cần được chỉ định giống như tên đã được cung cấp trong cài đặt SQL Server 2022.
"ConnectionStrings": {
"DefaultDatabase": "Server=DESKTOP-OMPTY7T\\SQLEXPRESS;Database=SampleCore;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
Các dịch vụ như ngữ cảnh cơ sở dữ liệu (DB context) cần được đăng ký trong bộ chứa tiêm phụ thuộc (dependency injection container) trong ứng dụng. Do đó, trong Solution Explorer, chỉnh sửa tệp Program.cs và thêm mã được đánh dấu như sau:
using MyCodeFirstApproachDemo.Models;
using Microsoft.EntityFrameworkCore;
...
public static void Main(string[] args) {
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultDatabase")
));
...
}
Giải thích:
- Phương thức CreateBuilder(string[]) của WebApplication khởi tạo một thể hiện mới của lớp WebApplicationBuilder.
- Kể từ .NET 6 trở đi, Microsoft đã hợp nhất tệp Startup.cs và Program.cs thành một tệp Program.cs duy nhất để thúc đẩy việc sử dụng APIs tối giản (Minimal APIs). Hai loại mới là WebApplication và WebApplicationBuilder được giới thiệu để giúp việc tạo ứng dụng Web dễ dàng hơn.
WebApplicationBuilder chịu trách nhiệm cho các tác vụ sau:
- Thêm cấu hình bằng cách sử dụng builder.Configuration.
- Thêm dịch vụ bằng cách sử dụng builder.Services.
- Cấu hình ghi nhật ký bằng cách sử dụng builder.Logging.
- Tổng hợp cấu hình HostBuilder và WebHostBuilder.
Lớp này đại diện cho một trình xây dựng ứng dụng Web và dịch vụ.
Do đó, nhu cầu đăng ký DbContext hiện đã được thêm vào tệp Program.cs.
Mở công cụ NuGet Package Manager
Điều này nghĩa là lấy dữ liệu từ SQL Server.
Để làm như vậy, mở bảng điều khiển NuGet Package Manager:
Trong Visual Studio, nhập lệnh sau:
add-migration MigrationName
Ở đây, MigrationName cần được thay thế bằng một tên có ý nghĩa hơn.
Hình 3.17 hiển thị rằng lệnh được thực thi thành công và việc xây dựng dự án đã hoàn tất.
Tự động trong Visual Studio, một tệp có tên MigrationName.cs sẽ được tạo, như hiển thị trong Hình 3.18. Tệp này chứa định nghĩa cho một lớp MigrationName.
Tập lệnh di chuyển (migration script) này giúp tạo cơ sở dữ liệu và các bảng trong SQL Server 2022.
Hoàn tất di chuyển
- Cuối cùng, trong Package Manager Console, nhập lệnh sau để cập nhật cơ sở dữ liệu:
update-database
Nhấn Enter, như minh họa trong Hình 3.19.
Trong MS SQL Server 2022, một cơ sở dữ liệu SampleCore sẽ được tạo ra. Dưới mục Tables, bảng Customer sẽ được tạo như hiển thị trong Hình 3.20.
- Nhấp chuột phải vào thư mục Controllers trong Solution Explorer và chọn Add > Controller.
- Đặt tên tệp là CustomerController.
- Thêm đoạn mã được hiển thị phía dưới vào tệp CustomerController.cs.
Đoạn mã này sẽ đảm bảo các thao tác cần thiết trên trang web được xử lý phù hợp.
public class CustomerController : Controller {
CustomerContext _context;
public CustomerController(CustomerContext context) {
_context = context;
}
public IActionResult Create() {
return View();
}
[HttpPost]
public ActionResult Create(Customer objCustomer) {
_context.Customer.Add(objCustomer);
_context.SaveChanges();
return View();
}
}
Nhấp chuột phải vào phương thức Create()
thứ hai và chọn Add View từ menu ngữ cảnh.Trong hộp thoại Add New Scaffolded Item, chọn Razor View. Xem minh họa trong Hình 3.21.
Hình 3.22: Thêm Razor View cho Create
- Chỉ định các tùy chọn từ danh sách thả xuống như được hiển thị trong Hình 3.22:
- Template: Chọn “Create”.
- Model class: Chọn lớp “Customer”.
- Data context class: Chọn “CustomerContext”.
- View name: Tên mặc định là “Create”.
- Đánh dấu tùy chọn “Use a layout page” nếu cần.
- Nhấp vào Add.
Khi thực hiện xong, một tệp View có tên Create.cshtml sẽ được tạo trong thư mục con Views/Customer.
Chạy và kiểm tra ứng dụng: Điều hướng đến URL:
https://localhost:7128/Customer/Create
Khi nhấp vào nút Create:
- Bản ghi sẽ được thêm vào bảng
Customer
trong cơ sở dữ liệu SQL Server. - Tương tự như chức năng Create, bạn cũng có thể tạo các View cho các thao tác Edit, Update và Delete.
Mẹo xử lý lỗi:
Lỗi lệnh add-migration
không được nhận dạng:
Cài đặt gói sau thông qua NuGet Package Manager:
Microsoft.EntityFrameworkCore.Tools
Lỗi InvalidOperationException
: View <ViewName>
không tìm thấy:
Mở dự án của bạn trong Solution Explorer, nhấp chuột phải và thêm gói NuGet:
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
Sau đó, thêm dòng lệnh sau vào file Program.cs
:
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
Lỗi The certificate chain was issued by an authority that is not trusted
:
Khi kết nối đến cơ sở dữ liệu, hãy đảm bảo rằng bạn có dòng:
TrustServerCertificate=True
Lưu ý: Điều này không được khuyến nghị trong môi trường thực tế.