Quản lý trạng thái thực thể trong EF Core bằng Attach và Entry

Khi làm việc với Entity Framework (EF) Core, chúng ta thường sử dụng phương thức SaveChanges() để lưu các thay đổi vào cơ sở dữ liệu. Tuy nhiên, cách mà EF Core xác định một thực thể cần được thêm mới, cập nhật hay xóa là gì? Điều này dựa trên trạng thái của thực thể (EntityState) được quản lý bởi EF Core. Trạng thái của thực thể có thể nằm trong năm loại sau:
  • Detached: Thực thể tồn tại nhưng không được theo dõi bởi dịch vụ đối tượng. Ví dụ: khi bạn tạo một đối tượng mới nhưng chưa thêm nó vào bối cảnh.
  • Unchanged: Đối tượng đã được tải vào bối cảnh và không có bất kỳ thay đổi nào kể từ lần gọi cuối cùng của SaveChanges().
  • Added: Đối tượng đã được thêm vào bối cảnh nhưng chưa gọi SaveChanges().
  • Deleted: Đối tượng đã được đánh dấu để xóa khỏi bối cảnh.
  • Modified: Đối tượng đã bị thay đổi và đang chờ được cập nhật vào cơ sở dữ liệu.

Phương thức Attach

Attach() được sử dụng để gắn một thực thể vào bối cảnh với trạng thái Unchanged. Điều này giúp EF Core biết rằng thực thể đó hiện đang được theo dõi, nhưng không yêu cầu lưu bất kỳ thay đổi nào vào cơ sở dữ liệu. Để sử dụng Attach(), cần đảm bảo:
  1. Nếu trong bối cảnh đã tồn tại một thực thể khác có khóa chính giống hệt, thì cả hai phải trỏ đến cùng một đối tượng trong bộ nhớ.
  2. Nếu không tồn tại thực thể nào tương tự, thực thể mới phải hoàn toàn độc lập (không bị trùng địa chỉ bộ nhớ).
Một ví dụ về cách sử dụng Attach() trong trường hợp xóa thực thể:

public int Xoa(ThucThe entity)
{
    DB.Set<ThucThe>().Attach(entity);
    DB.Set<ThucThe>().Remove(entity);
    return DB.SaveChanges();
}

Phương thức Entry

Entry() cho phép bạn lấy thông tin chi tiết về một thực thể cụ thể, bao gồm trạng thái hiện tại của nó. Nếu thực thể chưa từng được thêm vào bối cảnh, trạng thái sẽ là Detached. Ví dụ dưới đây minh họa cách sử dụng Entry() để cập nhật một số thuộc tính nhất định của thực thể:

public int CapNhat(ThucThe entity, params string[] tenThuocTinh)
{
    var thongTinThucThe = DB.Entry(entity);

    // Đánh dấu thực thể là 'Unchanged'
    thongTinThucThe.State = EntityState.Unchanged;

    foreach (var thuocTinh in tenThuocTinh)
    {
        thongTinThucThe.Property(thuocTinh).IsModified = true;
    }

    return DB.SaveChanges();
}
Bằng cách sử dụng Entry(), bạn có thể kiểm soát chính xác những thuộc tính nào cần được cập nhật mà không ảnh hưởng đến phần còn lại của thực thể.

Thẻ: ef-core csharp entity-state

Đăng vào ngày 11 tháng 7 lúc 15:43