DBContext trong ASP.NET Core
Entity Framework cho phép bạn truy vấn, chèn, cập nhật và xóa dữ liệu, sử dụng các đối tượng Runtime Ngôn ngữ chung (CLR) được gọi là các thực thể. Entity Framework ánh xạ các thực thể và các mối quan hệ được xác định trong mô hình của bạn vào cơ sở dữ liệu. Nó cũng cung cấp các cơ sở để -
- Vật chất hóa dữ liệu được trả về từ cơ sở dữ liệu dưới dạng các đối tượng thực thể.
- Theo dõi những thay đổi đã được thực hiện cho các đối tượng.
- Xử lý đồng thời.
- Tuyên truyền thay đổi đối tượng trở lại cơ sở dữ liệu.
- Ràng buộc các đối tượng để điều khiển.
Lớp chính chịu trách nhiệm tương tác với dữ liệu dưới dạng đối tượng là DbContext. Cách được đề xuất để làm việc với ngữ cảnh là xác định một lớp xuất phát từ DbContext và hiển thị các thuộc tính Dbset đại diện cho các bộ sưu tập của các thực thể được chỉ định trong ngữ cảnh.
Về mặt logic, một DBContext ánh xạ tới một cơ sở dữ liệu cụ thể có một lược đồ mà DBContext hiểu được. Và trên lớp DBContext đó, bạn có thể tạo các thuộc tính là loại Dbset <T>. Tham số loại chung T sẽ là một loại thực thể như Nhân viên là một thực thể trong ứng dụng FirstAppDemo.
Thí dụ
Chúng ta hãy lấy một ví dụ đơn giản, trong đó chúng ta sẽ tạo một lớp DbContext. Ở đây, chúng ta cần thêm một lớp mới trong thư mục Mô hình và gọi nó là FirstAppDempDbContext. Mặc dù bản thân lớp này không phải là một mô hình, nhưng nó kết hợp tất cả các Mô hình của chúng ta để chúng ta có thể sử dụng chúng với cơ sở dữ liệu.
Kế thừa lớp ngữ cảnh của bạn từ lớp DbContext trong không gian tên Miscrosoft.Data.Entity. Bây giờ thực hiện một Dbset của nhân viên trên lớp đó.
Mỗi DbSet sẽ ánh xạ tới một bảng trong cơ sở dữ liệu. Nếu bạn có một tài sản Dbset của nhân viên và tên của tài sản đó là Nhân viên, thì Entity Framework sẽ mặc định tìm một bảng Nhân viên trong cơ sở dữ liệu của bạn.
using FirstAppDemo.Models; using Microsoft.Data.Entity; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace OdeToFood.Models { public class FirstAppDemoDbContext : DbContext { public DbSet<Employee> Employees { get; set; } } }
Việc thực hiện rất đơn giản vì chúng tôi chỉ có một mô hình duy nhất để làm việc. Chúng tôi chỉ cần một tài sản, Dbset of Employee và chúng tôi có thể đặt tên cho tài sản này là Nhân viên.
Bây giờ chúng ta chèn trực tiếp lớp này vào các bộ điều khiển và sau đó các bộ điều khiển có thể sử dụng FirstAppDemoDbContext để truy vấn cơ sở dữ liệu. Chúng tôi sẽ đơn giản hóa tất cả những điều này bằng cách thêm một lớp mới vào lớp HomeContoder trong đó chúng tôi triển khai các phương thức để Thêm nhân viên và Nhận nhân viên như trong chương trình sau.
using Microsoft.AspNet.Mvc; using FirstAppDemo.ViewModels; using FirstAppDemo.Services; using FirstAppDemo.Entities; using FirstAppDemo.Models; using System.Collections.Generic; using System.Linq; namespace FirstAppDemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var model = new HomePageViewModel(); using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); model.Employees = sqlData.GetAll(); } return View(model); } } public class SQLEmployeeData { private FirstAppDemoDbContext _context { get; set; } public SQLEmployeeData(FirstAppDemoDbContext context) { _context = context; } public void Add(Employee emp) { _context.Add(emp); _context.SaveChanges(); } public Employee Get(int ID) { return _context.Employees.FirstOrDefault(e => e.Id == ID); } public IEnumerable<Employee> GetAll() { return _context.Employees.ToList<Employee>(); } } public class HomePageViewModel { public IEnumerable<Employee> Employees { get; set; } } }
Trong lớp SQLEmployeeData ở trên, bạn có thể thấy rằng chúng ta đã định nghĩa phương thức Add sẽ thêm một đối tượng nhân viên mới vào ngữ cảnh và sau đó nó sẽ lưu các thay đổi. Trong phương thức Nhận, nó sẽ trả về một nhân viên dựa trên ID. Trong khi đó, trong phương thức GetAll, nó sẽ trả về danh sách tất cả các nhân viên trong cơ sở dữ liệu.
Định cấu hình Dịch vụ khung thực thể
Để có một DBContext Entity Framework có thể sử dụng, chúng ta cần thay đổi cấu hình của ứng dụng. Chúng tôi sẽ cần thêm một chuỗi kết nối để DBContext của chúng tôi biết nên truy cập máy chủ nào và cơ sở dữ liệu nào để truy vấn.
- Chúng tôi sẽ đặt chuỗi kết nối trong tệp cấu hình JSON.
- Chúng ta cũng cần thêm một số dịch vụ khác trong phương thức ConfigureService của lớp Khởi động.
- Entity Framework, giống như ASP.NET và MVC framework, Entity Framework dựa vào phép tiêm phụ thuộc và để hoạt động tiêm, bộ thực thi cần biết về các dịch vụ khác nhau mà Entity Framework sử dụng.
- Có một API cấu hình dễ dàng sẽ thêm tất cả các dịch vụ mặc định mà chúng ta cần.
Chúng ta hãy truy cập tệp AppSinstall.json và thêm chuỗi kết nối như trong chương trình sau.
{ "message": "Hello, World! this message is from configuration file...", "database": { "connection": "Data Source=(localdb)\\mssqllocaldb;Initial Catalog=FirstAppDemo" } }
Bây giờ chúng ta hãy đến lớp Khởi động nơi chúng ta cần thêm một số dịch vụ bổ sung để Entity Framework hoạt động chính xác. Cụ thể, có ba điều chúng ta cần làm có liên quan đến Khung thực thể -
- Chúng ta cần thêm các dịch vụ Entity Framework cốt lõi.
- Chúng ta cũng cần thêm các dịch vụ Entity Framework liên quan đến SQL Server.
- Chúng ta cần nói với Entity Framework về DBContext của chúng ta.
Tất cả điều này có thể được thực hiện thông qua các phương thức có sẵn dưới dạng phương thức mở rộng trên IServiceCollection như được hiển thị trong chương trình sau.
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext> (option => option.UseSqlServer(Configuration["database:connection"])); }
- Phương thức đầu tiên là AddEntityFramework. Điều này sẽ thêm các dịch vụ Entity Framework cốt lõi, các dịch vụ mặc định.
- Nhưng vì Entity Framework hiện được thiết kế để hoạt động với các loại cơ sở dữ liệu khác nhau, bao gồm cả cơ sở dữ liệu không liên quan, chúng tôi cần thực hiện cuộc gọi thứ hai để thông báo cho Entity Framework để thêm các dịch vụ liên quan đến SQL Server mặc định của nó.
- Sau đó, chúng ta cũng cần nói với Entity Framework về lớp DBContext của mình để nó có thể xây dựng các thể hiện của lớp đó một cách thích hợp và chúng ta có thể thực hiện điều đó thông qua một phương thức thứ ba, phương thức AddDbContext.
- Cái này lấy tham số kiểu chung trong đó chúng ta chỉ định loại của lớp dẫn xuất DBContext, FirstAppDemoDbContext.
- Bên trong AddDbContext, chúng tôi cần mô tả các tùy chọn cho DBContext của chúng tôi.
- Điều này có thể được thực hiện bởi một biểu thức lambda; đó là một hành động trong đó chúng tôi nhận được một tham số tùy chọn và Entity Framework có thể hỗ trợ các cơ sở dữ liệu khác nhau. Tất cả những gì chúng ta cần làm là, nói với Entity Framework rằng DBContext cụ thể này sẽ sử dụng UseSqlServer.
- Phương thức này yêu cầu một tham số là ConnectionString để sử dụng.
- Sau đây là việc thực hiện đầy đủ tệp Startup.cs.
using Microsoft.AspNet.Mvc; using FirstAppDemo.ViewModels; using FirstAppDemo.Services; using FirstAppDemo.Entities; using FirstAppDemo.Models; using System.Collections.Generic; using System.Linq; namespace FirstAppDemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var employee = new Employee { Id = 1, Name = "Mark Upston1" }; using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); sqlData.Add(employee); } //var employee = new Employee { ID = 1, Name = "Mark Upston" }; return View(employee); } } public class SQLEmployeeData { private FirstAppDemoDbContext _context { get; set; } public SQLEmployeeData(FirstAppDemoDbContext context) { _context = context; } public void Add(Employee emp) { _context.Add(emp); _context.SaveChanges(); } public Employee Get(int ID) { return _context.Employees.FirstOrDefault(e => e.Id == ID); } public IEnumerable<Employee> GetAll() { return _context.Employees.ToList<Employee>(); } } }
Bây giờ chúng ta cần thiết lập cơ sở dữ liệu. Một cách để thiết lập cơ sở dữ liệu là sử dụng Khung thực thể để tạo cơ sở dữ liệu và đây là quy trình gồm hai bước -
Bước đầu tiên
Điều này liên quan đến những điều sau đây -
- Thêm mã di chuyển vào dự án của chúng tôi.
- Mã di chuyển là mã C #. Điều này có thể được thực thi để tạo cơ sở dữ liệu trong lược đồ cơ sở dữ liệu.
- Entity Framework có thể tạo mã di chuyển này cho chúng tôi.
- Entity Framework xem xét cơ sở dữ liệu và các mô hình của chúng tôi và tìm ra những thay đổi lược đồ được yêu cầu để làm cho ứng dụng hoạt động.
- Vì vậy, khi chúng tôi thêm các mô hình bổ sung hoặc thay đổi các mô hình hiện có, như lớp Nhân viên, chúng tôi có thể tiếp tục thêm di chuyển vào dự án của chúng tôi và giữ cho lược đồ cơ sở dữ liệu của chúng tôi đồng bộ.
Bước thứ hai
Điều này liên quan đến những điều sau đây -
- Ở đây, chúng ta cần áp dụng rõ ràng những di chuyển đó để cập nhật cơ sở dữ liệu.
- Cả hai tác vụ này đều có thể đạt được bằng cách sử dụng một số lệnh dễ dàng từ cửa sổ giao diện điều khiển.
- Chúng tôi đã thực hiện project.json.
- Đó là lý do tại sao chúng tôi đã tạo ra project.json để thêm một lệnh trong đó bản đồ ef trực tiếp vào EntityFramework.Commands.
Chúng ta hãy mở Dấu nhắc lệnh dành cho nhà phát triển cho Visual Studio để chạy các lệnh mà chúng ta cần để thêm các lần di chuyển và áp dụng các lần di chuyển. Cách dễ nhất để làm điều này là vào thư mục gốc của ứng dụng.
Nếu bạn đang ở trong thư mục có tệp project.json, thì bạn đang ở đúng thư mục. Ở đây, chúng ta cần thực thi một lệnh được gọi là dnvm. Đây là trình quản lý phiên bản .NET sẽ cho hệ thống biết thời gian chạy mà chúng ta muốn sử dụng.
Bây giờ chúng ta sử dụng lệnh sau.
danh sách dnvm
Bạn sẽ thấy đầu ra sau đây khi bạn nhấn Enter.
Chúng tôi cần nói với dnvm rằng chúng tôi muốn sử dụng thời gian chạy cụ thể. Điều này sẽ cho chúng ta quyền truy cập vào lệnh dotnet hoặc lệnh dnx mà chúng ta muốn thực thi.
Thực hiện lệnh sau.
dnvm sử dụng1.0.0-rc1-update1 -p
Bấm phím Enter.
dnvm sẽ thiết lập đường dẫn của chúng tôi và các biến môi trường để bao gồm một thư mục bin sẽ cho phép chúng tôi truy cập vào tiện ích dnx này. Hãy để chúng tôi thực hiện lệnh dnx ef.
Đây là môi trường thực thi .NET, sử dụng dnx, chúng ta có thể gọi các lệnh mà chúng ta đã liệt kê trong tệp project.json. Thực hiện các lệnh này thường rất dễ dàng. Khi bạn gõ dnx ef, bạn sẽ nhận được màn hình trợ giúp. Bạn không cần phải nhớ tất cả các tùy chọn. Bạn có thể thấy các lệnh có sẵn từ các Lệnh Khung thực thể và có ba trong số chúng.
Đầu tiên, chúng ta cần thêm di chuyển để thực hiện lệnh sau.
di chuyển dnx ef thêm v1
Bấm phím Enter.
Entity Framework sẽ tìm thấy bối cảnh đó và xem xét các mô hình bên trong. Nó sẽ biết rằng không có di chuyển trước đó và vì vậy nó sẽ tạo ra di chuyển đầu tiên. Ở đây, v1 là phiên bản 1 của cơ sở dữ liệu. Nó sẽ tạo một thư mục mới trong Solution Explorer và tạo mã.
A migration is essentially a C# code that is used to generate SQL commands to modify the schema in a SQL database.
using System; using System.Collections.Generic; using Microsoft.Data.Entity.Migrations; using Microsoft.Data.Entity.Metadata; namespace FirstAppDemo.Migrations { public partial class v1 : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable(name: "Employee", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), Name = table.Column<string>(nullable: true) }, constraints: table => { table.PrimaryKey("PK_Employee", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable("Employee"); } } }
Bạn có thể thấy nó sẽ tạo ra một bảng gọi là Nhân viên.
Bảng này phải có hai cột - ID và cột Tên.
Theo quy ước, khi Khung thực thể thấy rằng bạn có một thuộc tính được gọi là Id, nó sẽ biến thuộc tính đó hoặc, thay vào đó, làm cho cột đó trở thành khóa chính trong cơ sở dữ liệu.
Ở đây, chúng tôi sẽ sử dụng SQL Server. Theo mặc định, Khung thực thể sẽ tạo ra một IdentityColumn, có nghĩa là Máy chủ SQL sẽ tạo ID cho chúng tôi.
Hãy để chúng tôi áp dụng các ID này cho cơ sở dữ liệu bằng cách gõ lệnh cập nhật cơ sở dữ liệu của dnx ef.
Bạn có thể thấy rằng lệnh đã áp dụng di chuyển.
Bây giờ chúng ta hãy đến SQL Server Object Explorer và làm mới cơ sở dữ liệu, bây giờ bạn có thể thấy chúng tôi có cơ sở dữ liệu FirstAppDemo.
Bạn cũng có thể thấy bảng Nhân viên của chúng tôi và chúng tôi thậm chí có thể xem các cột cho bảng đó trong đó cột ID là khóa chính.
Hãy để chúng tôi nhấp chuột phải vào bảng dbo.Employee và chọn Xem dữ liệu.
Trước khi chúng tôi chạy ứng dụng, chúng ta hãy thêm một số dữ liệu. Khi chúng tôi khởi chạy ứng dụng, chúng tôi sẽ thấy một số dữ liệu từ cơ sở dữ liệu.
Hãy để chúng tôi chỉ cần thêm một vài hàng dữ liệu ở đây.
@model FirstAppDemo.Controllers.HomePageViewModel <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Home</title> </head> <body> <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table> </body> </html>