Có hai lớp:
public class Parent
{
public int Id { get; set; }
public int ChildId { get; set; }
}
public class Child { ... }
Khi gán ChildId
cho Parent
tôi nên kiểm tra trước nếu nó tồn tại trong DB hoặc đợi DB ném ngoại lệ?
Ví dụ: (sử dụng Entity Framework Core):
LƯU Ý các loại kiểm tra này TẤT CẢ QUẢNG CÁO ngay cả trên các tài liệu chính thức của Microsoft: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-USE- mvc / xử lý-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application # Sửa-bộ-bộ-điều khiển nhưng có xử lý ngoại lệ bổ sung choSaveChanges
đồng thời, lưu ý rằng mục đích chính của kiểm tra này là trả lại thông báo thân thiện và trạng thái HTTP đã biết cho người dùng API và không bỏ qua hoàn toàn các ngoại lệ cơ sở dữ liệu. Và ngoại lệ duy nhất được ném là bên trong SaveChanges
hoặc SaveChangesAsync
gọi ... vì vậy sẽ không có ngoại lệ khi bạn gọi FindAsync
hoặc Any
. Vì vậy, nếu con tồn tại nhưng đã bị xóa trước SaveChangesAsync
đó thì ngoại lệ đồng thời sẽ bị ném.
Tôi đã làm điều này do một thực tế là foreign key violation
ngoại lệ sẽ khó định dạng hơn để hiển thị "Không thể tìm thấy trẻ em với id {Parent.ChildId}."
public async Task<ActionResult<Parent>> CreateParent(Parent parent)
{
// is this code redundant?
// NOTE: its probably better to use Any isntead of FindAsync because FindAsync selects *, and Any selects 1
var child = await _db.Children.FindAsync(parent.ChildId);
if (child == null)
return NotFound($"Child with id {parent.ChildId} could not be found.");
_db.Parents.Add(parent);
await _db.SaveChangesAsync();
return parent;
}
đấu với:
public async Task<ActionResult<Parent>> CreateParent(Parent parent)
{
_db.Parents.Add(parent);
await _db.SaveChangesAsync(); // handle exception somewhere globally when child with the specified id doesn't exist...
return parent;
}
Ví dụ thứ hai trong Postgres sẽ đưa 23503 foreign_key_violation
ra lỗi: https://www.postgresql.org/docs/9.4/static/errcodes-appcill.html
Nhược điểm của việc xử lý các trường hợp ngoại lệ theo cách này trong ORM như EF là nó sẽ chỉ hoạt động với một phụ trợ cơ sở dữ liệu cụ thể. Nếu bạn từng muốn chuyển sang máy chủ SQL hoặc thứ gì khác thì nó sẽ không hoạt động nữa vì mã lỗi sẽ thay đổi.
Không định dạng ngoại lệ đúng cho người dùng cuối có thể phơi bày một số điều bạn không muốn bất kỳ ai ngoài nhà phát triển thấy.
Liên quan:
https://stackoverflow.com/questions/4189954/im Hiện
https://stackoverflow.com/questions/308905/should-there-be-a-transaction-for-read-queries
Child with id {parent.ChildId} could not be found.
. Và định dạng "Vi phạm khóa ngoài" Tôi nghĩ là tồi tệ hơn trong trường hợp này.