Trong quy trình phê duyệt, tôi muốn đảm bảo rằng các email nhắc nhở được gửi chính xác một lần.EF eqivalent cho các hàng bị ảnh hưởng của SqlCommand.ExecuteNonQuery
Với SqlCommand.ExecuteNonQuery Tôi có thể đảm bảo điều này bằng cách kiểm tra giá trị trả lại. Giải pháp được khuyến nghị sử dụng EF là gì? Theo tài liệu ObjectContext.SaveChanges không trả lại giá trị tương đương.
SqlCommand dụ: (The TransactionScope được sử dụng để rollback cập nhật DB trong trường hợp SendMail thất bại.)
Dim sql = "UPDATE LeaveApprovalRequests SET State = 'Reminded'" &
" WHERE ID=3 AND State <>'Reminded'"
Using scope As New TransactionScope
Using cnx As New SqlConnection(My.Settings.connectionString)
cnx.Open()
Dim cmd As New SqlCommand(sql, cnx)
If 1 = cmd.ExecuteNonQuery Then
SendMail()
End If
scope.Complete()
End Using
End Using
Bằng cách cho phép đồng thời lạc quan (sử dụng ConcurrencyMode = cố định trên một tài sản rowversion) và bắt OptimisticConcurrencyException tôi có thể xác định xem đối tượng có thực sự được cập nhật trong cửa hàng hay không. Bây giờ TransactionScope (được sử dụng để khôi phục bản cập nhật DB nếu SendMail không thành công) ném một lỗi bế tắc. Tại sao?
Using scope As New TransactionScope
Using ctx As New ApprovalEntities
Try
Dim approval = ctx.LeaveApprovalRequests.
Where(Function(r) r.ID = 3 And r.State = "Created"
).FirstOrDefault
If approval Is Nothing Then
Console.WriteLine("not found")
Exit Sub
End If
Threading.Thread.Sleep(4000)
approval.State = "Reminded"
ctx.SaveChanges()
SendMail()
Catch ex As OptimisticConcurrencyException
Exit Try
End Try
End Using
scope.Complete()
End Using
Đối với tôi, tài liệu cho biết SaveChanges trả về số lượng đối tượng dự định cập nhật, không phải số mà nó cập nhật trong cửa hàng. Tôi đã xác minh điều này bằng cách thiết lập một điểm ngắt tại SaveChanges(), thay đổi giá trị trong SQL Server và sau đó tiếp tục. –
Chính xác. Và nếu bạn có thể gọi SaveChanges() * mà không có bất kỳ ngoại lệ nào, thì EF đảm bảo rằng số lượng đối tượng dự định được cập nhật, thực sự được cập nhật trong cửa hàng hoặc bạn sẽ nhận được một ngoại lệ. –
Xin lỗi, tôi không đọc bình luận đầu tiên của bạn đúng cách (mặc dù bạn đã làm sáng tỏ phần quan trọng). Trường hợp thử nghiệm ban đầu của tôi không sử dụng đồng thời lạc quan, nhưng trong các kịch bản thế giới thực của tôi, tôi sẽ kích hoạt nó trong hầu hết các trường hợp. Đó là câu hỏi tại sao TransactionScope ném một lỗi bế tắc. –