Các thao tác với cơ sở dữ liệu trong Entity Framework

Trong hướng dẫn trước, chúng ta đã tìm hiểu ba cách khác nhau để định nghĩa mô hình dữ liệu thực thể.

  • Database First và Model First phụ thuộc vào trình thiết kế Entity Framework kết hợp với trình tự động tạo mã.
  • Code First cho phép bạn bỏ qua trình thiết thiết kế và chỉ cần viết mã của riêng bạn.
  • Bất kể bạn chọn cách tiếp cận nào, bạn sẽ kết thúc với một tập các lớp thực thể và một hoặc nhiều lớp DbContext của Entity Framework cho phép bạn truy xuất và duy trì dữ liệu liên quan đến các lớp đó.

Nếu bạn đã bỏ lỡ bài viết về ba cách tiếp cận Database First, Model First, Code First trong Entity Framework thì có thể xem tại đây:

Cách tiếp cận trong Entity Framework | Comdy
Cách tiếp cận Code First, Model First, Database First trong Entity Framework khác nhau như thế nào? Sử dụng khi nào?

DbContext API trong các ứng dụng của bạn được sử dụng làm cầu nối giữa các lớp và cơ sở dữ liệu của bạn. DbContext là một trong những lớp quan trọng nhất trong Entity Framework.

  • Nó cho phép tạo và thực hiện các truy vấn.
  • Nó lấy kết quả truy vấn từ cơ sở dữ liệu và biến chúng thành các thể hiện của các lớp thực thể trong mô hình.
  • Nó có thể theo dõi các thay đổi đối với các thực thể, bao gồm cả thêm và xóa thực thể. Sau đó nó sẽ tạo các câu lệnh insert, updatedelete tương ứng rồi gửi đến cơ sở dữ liệu để thực thi.

Sau đây là các lớp ngữ cảnh quảng cáo tên miền mà chúng tôi sẽ thực hiện các hoạt động khác nhau trong chương này. Đây là ví dụ tương tự mà chúng tôi đã tạo trong chapater, Cơ sở dữ liệu tiếp cận đầu tiên.

Thực hiện lớp Context

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

namespace DatabaseFirstDemo 
{
   public partial class UniContextEntities : DbContext 
   {
      public UniContextEntities(): base("name = UniContextEntities") 
      { }

      protected override void OnModelCreating(DbModelBuilder modelBuilder) 
      {
         throw new UnintentionalCodeFirstException();
      }

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }
}

Thực hiện các lớp thực thể

Lớp Course

using System;
using System.Collections.Generic;

namespace DatabaseFirstDemo 
{	
   public partial class Course 
   {
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]
      public Course() 
      {
         this.Enrollments = new HashSet<Enrollment>();
      }
	
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
	
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Lớp Student

using System;
using System.Collections.Generic; 

namespace DatabaseFirstDemo 
{
   public partial class Student 
   {
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]
      public Student() 
      {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Lớp Enrollment

using System;
using System.Collections.Generic; 

namespace DatabaseFirstDemo 
{
   public partial class Enrollment 
   {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Nullable<int> Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }
}

Thao tác thêm mới

Thêm một đối tượng mới với Entity Framework rất đơn giản. Bạn chỉ cần tạo một thể hiện mới của đối tượng và đăng ký nó bằng phương thức Add trên DbSet, sau đó gọi phương thức SaveChanges của Context là xong.

Đoạn mã sau minh họa thêm một sinh viên mới vào cơ sở dữ liệu.

class Program 
{
   static void Main(string[] args) 
   {
      var newStudent = new Student();

      //set student name
      newStudent.FirstMidName = "Bill";
      newStudent.LastName = "Gates";
      newStudent.EnrollmentDate = DateTime.Parse("2019-10-21");

      //create DBContext object
      using (var dbCtx = new UniContextEntities()) 
      {
         //Add Student object into Students DBset
         dbCtx.Students.Add(newStudent);

         // call SaveChanges method to save student into database
         dbCtx.SaveChanges();
      }
   }
}

Thao tác cập nhật

Cập nhật các thay đổi của một đối tượng với Entity Framework cũng rất đơn giản. Bạn chỉ cần cập nhật giá trị được gán cho (các) thuộc tính bạn muốn thay đổi sau đó gọi phương thức SaveChanges của Context là xong.

Ví dụ: đoạn mã sau được sử dụng để thay đổi họ của Ali từ Khan thành Aslam.

using (var context = new UniContextEntities()) 
{
   var student = (from d in context.Students 
                  where d.FirstMidName == "Ali" 
                  select d).FirstOrDefault();
                  
   student.LastName = "Aslam";
   context.SaveChanges();
}

Thao tác xóa

Để xóa một thực thể bằng Entity Framework, bạn sử dụng phương thức Remove trên DbSet.

Thực thể được xóa khỏi trình theo dõi thay đổi và không còn được theo dõi bởi DbContext. Nó sẽ được xóa khởi cơ sở dữ liệu khi phương thức SaveChanges được gọi.

Phương thức Remove cũng có thể thực thể hiện với các đối tượng mới được thêm nhưng chưa gọi SaveChanges để lưu vào cơ sở dữ liệu. Gọi Remove trên một thực thể đã được thêm nhưng chưa được lưu vào cơ sở dữ liệu sẽ hủy việc thêm thực thể đó.

Ví dụ sau đây minh họa xóa một sinh viên có tên Ali trong Entity Framework.

using (var context = new UniContextEntities()) 
{
   var student = (from d in context.Students 
                  where d.FirstMidName == "Ali" 
                  select d).FirstOrDefault();
              
   context.Students.Remove(student);
   context.SaveChanges();
}

Thao tác đọc

Bạn có thể đọc dữ liệu của một hoặc nhiều thực thể tùy ý theo điều kiện bạn cung cấp. Trong đoạn mã sau sẽ có hai phương thức lấy thông tin sinh viên theo Id và lấy danh sách sinh viên theo tên.

private static Student GetStudentById(int id) 
{
  using (var context = new UniContextEntities()) 
  {
	 var student = (from d in context.Students
					where d.ID == id 
					select d).FirstOrDefault();
					
	 return student;
  }
}

private static List<Student> GetStudentsByName(string name) 
{
  using (var context = new UniContextEntities()) 
  {
	 var students = (from d in context.Students
					where d.LastName == name
					select d).ToList();
					
	 return students;
  }
}


Bài viết liên quan:

2 kịch bản lưu dữ liệu trong Entity Framework Core là kịch bản được kết nối và kịch bản ngắt kết nối.

Tạo ứng dụng .NET Core Console đầu tiên và cấu hình sử dụng Entity Framework Core.

Truy vấn trong Entity Framework Core có gì mới? Truy vấn trong EF Core khác EF ở những điểm nào.