두 가지 수업이 있습니다.
public class Parent
{
public int Id { get; set; }
public int ChildId { get; set; }
}
public class Child { ... }
에 할당 ChildId
할 때 Parent
DB에 존재하는지 먼저 확인하거나 DB가 예외를 throw 할 때까지 기다려야합니까?
예를 들어 (Entity Framework Core 사용) :
주 검사의 이러한 종류는 온통의 인터넷 에도 공식 마이크로 소프트의 문서에 : https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using- mvc / 처리 동시성-엔티티 프레임 워크-ASP-net-mvc-application # modify-부서 컨트롤러- 추가 예외 처리가 있습니다.SaveChanges
또한이 확인의 주요 목적은 API 사용자에게 친숙한 메시지와 알려진 HTTP 상태를 반환하고 데이터베이스 예외를 완전히 무시하지 않는 것입니다. 그리고 발생 될 수있는 유일한 장소 예외는 내부에 SaveChanges
또는 SaveChangesAsync
전화는 전화 할 때 너무 예외가되지 않습니다 ... FindAsync
나 Any
. 따라서 자식이 존재하지만 이전에 삭제 된 SaveChangesAsync
경우 동시성 예외가 발생합니다.
foreign key violation
"ID가 {Child.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;
}
대:
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;
}
Postgres의 두 번째 예는 https://www.postgresql.org/docs/9.4/static/errcodes-appendix.html23503 foreign_key_violation
오류를 발생시킵니다.
EF와 같은 ORM에서 예외를 처리하는 단점은 특정 데이터베이스 백엔드에서만 작동한다는 것입니다. SQL 서버 또는 다른 것으로 전환하려는 경우 오류 코드가 변경되므로 더 이상 작동하지 않습니다.
최종 사용자를 위해 예외의 형식을 올바르게 지정하지 않으면 개발자 이외의 다른 사람이 원하지 않는 내용이 노출 될 수 있습니다.
관련 :
https://stackoverflow.com/questions/308905/should-there-be-a-transaction-for-read-queries
Child with id {parent.ChildId} could not be found.
. 그리고 "외국 키 위반"의 형식을 지정하면이 경우에 더 나빠집니다.