Khi bạn làm context.Entry(entity).State = EntityState.Modified;
, bạn không chỉ gắn thực thể vào DbContext
, bạn cũng đang đánh dấu toàn bộ thực thể là bẩn. Điều này có nghĩa là khi bạn làm context.SaveChanges()
, EF sẽ tạo một bản cập nhật sẽ cập nhật tất cả các trường của thực thể.
Điều này không phải lúc nào cũng mong muốn.
Mặt khác, DbSet.Attach(entity)
gắn đơn vị với bối cảnh mà không đánh dấu nó bẩn. Nó tương đương với việc thực hiện context.Entry(entity).State = EntityState.Unchanged;
Khi đính kèm theo cách này, trừ khi bạn tiến hành cập nhật thuộc tính trên thực thể, lần sau bạn gọi context.SaveChanges()
, EF sẽ không tạo bản cập nhật cơ sở dữ liệu cho thực thể này. Ngay cả khi bạn đang có ý định cập nhật thực thể, nếu thực thể có nhiều thuộc tính (cột db) nhưng bạn chỉ muốn cập nhật một vài, bạn có thể thấy thuận lợi khi thực hiện DbSet.Attach(entity)
và sau đó chỉ cập nhật vài thuộc tính cần cập nhật. Làm theo cách này sẽ tạo ra một tuyên bố cập nhật hiệu quả hơn từ EF. EF sẽ chỉ cập nhật các thuộc tính bạn đã sửa đổi (trái ngược với context.Entry(entity).State = EntityState.Modified;
sẽ làm cho tất cả các thuộc tính/cột được cập nhật)
Tài liệu liên quan: Add/Attach and Entity States.
Mã dụ
Hãy nói rằng bạn có thực thể sau:
public class Person
{
public int Id { get; set; } // primary key
public string FirstName { get; set; }
public string LastName { get; set; }
}
Nếu mã của bạn trông như thế này:
context.Entry(personEntity).State = EntityState.Modified;
context.SaveChanges();
SQL được tạo ra sẽ giống như thế này:
UPDATE person
SET FirstName = 'whatever first name is',
LastName = 'whatever last name is'
WHERE Id = 123; -- whatever Id is.
Lưu ý cách câu lệnh cập nhật ở trên sẽ cập nhật tất cả các cột, bất kể bạn có thực sự thay đổi giá trị hay không.
Ngược lại, nếu mã của bạn sử dụng "bình thường" Đính kèm như thế này:
context.People.Attach(personEntity); // State = Unchanged
personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty.
context.SaveChanges();
Sau đó, báo cáo cập nhật được tạo ra là khác nhau:
UPDATE person
SET FirstName = 'John'
WHERE Id = 123; -- whatever Id is.
Như bạn có thể thấy, các báo cáo cập nhật chỉ cập nhật các giá trị đã thực sự thay đổi sau khi bạn đính kèm thực thể vào ngữ cảnh. Tùy thuộc vào cấu trúc bảng của bạn, điều này có thể có tác động hiệu suất tích cực.
Bây giờ, tùy chọn nào tốt hơn cho bạn phụ thuộc hoàn toàn vào những gì bạn đang cố gắng làm.
Tốt hơn hãy thêm một số thông tin phiên bản, điều này đã được yêu cầu trước đó. Tôi không rõ nếu điều này xứng đáng là một câu hỏi mới. –