EF 6 - Lưu dữ liệu bị ngắt kết nối
Lưu dữ liệu trong kịch bản bị ngắt kết nối
Lưu dữ liệu trong kịch bản bị ngắt kết nối hơi khác một chút so với kịch bản được kết nối.
Trong kịch bản bị ngắt kết nối, một thể thể của DbContext
không biết về các thực thể bị ngắt kết nối vì các thực thể được tạo hoặc sửa đổi ngoài phạm vi của DbContext
thể hiện hiện tại.
Vì vậy, bạn cần phải đính kèm các thực thể bị ngắt kết nối với một Context với trạng thái EntityState
phù hợp để thực hiện các thao tác INSERT hoặc UPDATE trong cơ sở dữ liệu.
Trong kịch bản bị ngắt kết nối, bạn cần tìm hiểu xem một thực thể là thêm mới hay hiện có và dựa vào đó bạn có thể thiết lập trạng thái EntityState
.
Ở đây, nếu giá trị thuộc tính khóa bằng 0 thì chúng tôi sẽ coi đó là một thực thể mới và vì vậy chúng tôi sẽ thiết lập trạng thái là Added
.
Nếu giá trị thuộc tính khóa lớn hơn 0, thì có nghĩa là nó là một thực thể hiện có và vì vậy chúng tôi sẽ đặt trạng thái là Modified
.
Ưu điểm:
- Sử dụng ít tài nguyên hơn so với kịch bản được kết nối.
- Không mở kết nối với cơ sở dữ liệu.
Nhược điểm:
- Cần đặt trạng thái thích hợp cho từng thực thể trước khi lưu.
- Thực hiện chậm hơn so với kịch bản được kết nối.
Thêm mới dữ liệu trong kịch bản bị ngắt kết nối
Ví dụ sau đây cho thấy việc lưu một thực thể bị ngắt kết nối.
// disconnected new entity
var student = new Student()
{
StudentName = "Bill"
};
using (var context = new SchoolDBEntities())
{
context.Entry(student).State = student.StudentId == 0 ? EntityState.Added : EntityState.Modified;
context.SaveChanges();
}
Trong ví dụ trên, student
là một đối tượng thực thể bị ngắt kết nối và context
không biết được trạng thái của nó.
Đoạn mã context.Entry(student).State = student.StudentId == 0 ? EntityState.Added : EntityState.Modified;
sẽ thiết lập trạng thái Added
nếu giá trị của thuộc tính khóa StudentId
bằng 0, ngược lại nó sẽ thiết lập trạng thái là Modified
. Phương thức SaveChanges()
sẽ tạo và thực hiện lệnh INSERT sau vào cơ sở dữ liệu.
exec sp_executesql N'INSERT [dbo].[Student]([StudentName], [StandardId])
VALUES (@0, NULL)
SELECT [StudentID] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity(),@0='Bill'
Cập nhật dữ liệu trong kịch bản bị ngắt kết nối
Tương tự, nếu giá trị của StudentId
khác 0, thì nó sẽ thiết lập trạng thái EntityState
là Modified
và do đó khi gọi phương thức SaveChanges()
sẽ thực thi lệnh UPDATE.
// disconnected existing entity
var student = new Student()
{
StudentId = 1,
StudentName = "Steve"
};
using (var context = new SchoolDBEntities())
{
context.Entry(student).State = student.StudentId == 0 ? EntityState.Added : EntityState.Modified;
context.SaveChanges();
}
Trong ví dụ trên, một đối tượng của thực thể Student
có thuộc tính khóa StudentId
lớn hơn 0, vì vậy nó sẽ được đánh dấu là Modified
. Điều này sẽ thực hiện lệnh UPDATE sau trong cơ sở dữ liệu.
exec sp_executesql N'UPDATE [dbo].[Student]
SET [StudentName] = @0
WHERE @@ROWCOUNT > 0 AND [StudentID] = @1'N'@0 varchar(50),@1 int',@0='Steve',@1=1
Xóa dữ liệu trong kịch bản bị ngắt kết nối
Xóa một thực thể bị ngắt kết nối rất dễ dàng. Chỉ cần đặt trạng thái thành Deleted
bằng phương thức Entry()
như ví dụ dưới đây.
// disconnected entity to be deleted
var student = new Student()
{
StudentId = 1
};
using (var context = new SchoolDBEntities())
{
context.Entry(student).State = System.Data.Entity.EntityState.Deleted;
context.SaveChanges();
}
Trong ví dụ trên, một thể hiện của thực thể Student
chỉ chứa thuộc tính khóa StudentId
. Để xóa một thực thể, nó chỉ yêu cầu một thuộc tính khóa. Câu lệnh context.Entry(student).State = System.Data.Entity.EntityState.Deleted
sẽ gắn một thực thể vào một Context và gán trạng thái của nó thành Deleted
. Điều này sẽ thực hiện lệnh DELETE sau trong cơ sở dữ liệu.
exec sp_executesql N'DELETE [dbo].[Students]
WHERE ([StudentId] = @0)',N'@0 int',@0=1
Go