Entity Framework를 사용하는 프로젝트가 있습니다. SaveChanges
내 전화하는 동안 DbContext
다음 예외가 발생합니다.
System.Data.Entity.Validation.DbEntityValidationException : 하나 이상의 엔티티에 대한 유효성 검증에 실패했습니다. 자세한 내용은 ‘EntityValidationErrors’속성을 참조하십시오.
이것은 모두 훌륭하고 멋지지만이 예외가 발생할 때마다 디버거를 연결하고 싶지 않습니다. 또한 프로덕션 환경에서는 디버거를 쉽게 연결할 수 없으므로 이러한 오류를 재현하기 위해 많은 시간을 투자해야합니다.
안에 숨겨진 세부 정보를 어떻게 볼 수 DbEntityValidationException
있습니까?
답변
가장 쉬운 해결책은 SaveChanges
엔터티 클래스 에서 재정의 하는 것입니다. 을 포착하고 DbEntityValidationException
실제 오류를 풀고 DbEntityValidationException
개선 된 메시지 로 새 메시지를 작성할 수 있습니다 .
- SomethingSomething.Context.cs 파일 옆에 부분 클래스를 작성하십시오.
- 이 게시물의 맨 아래에있는 코드를 사용하십시오.
- 그게 다야. 구현시 리팩터링 작업없이 재정의 된 SaveChanges를 자동으로 사용합니다.
예외 메시지는 이제 다음과 같습니다.
System.Data.Entity.Validation.DbEntityValidationException : 하나 이상의 엔티티에 대한 유효성 검증에 실패했습니다. 자세한 내용은 ‘EntityValidationErrors’속성을 참조하십시오. 유효성 검사 오류는 다음과 같습니다. PhoneNumber 필드는 최대 길이가 ’12’인 문자열 또는 배열 유형이어야합니다. 성 필드는 필수입니다.
다음에서 상속되는 모든 클래스에서 재정의 된 SaveChanges를 삭제할 수 있습니다 DbContext
.
public partial class SomethingSomethingEntities
{
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
}
는 DbEntityValidationException
또한 유효성 검사 오류를 발생시킨 개체가 포함되어 있습니다. 따라서 더 많은 정보가 필요한 경우 위 코드를 변경하여 해당 엔티티에 대한 정보를 출력 할 수 있습니다.
참조 : http://devillers.nl/improving-dbentityvalidationexception/
답변
Martin이 지적했듯이,에 더 많은 정보가 있습니다 DbEntityValidationResult
. 각 메시지에서 POCO 클래스 이름과 속성 이름을 모두 얻는 것이 유용하다는 것을 알았으며 ErrorMessage
모든 사용자 정의 속성 을 작성하지 않아도되었습니다.[Required]
태그 했습니다.
Martin의 코드를 다음과 같이 조정하면 이러한 세부 사항을 처리했습니다.
// Retrieve the error messages as a list of strings.
List<string> errorMessages = new List<string>();
foreach (DbEntityValidationResult validationResult in ex.EntityValidationErrors)
{
string entityName = validationResult.Entry.Entity.GetType().Name;
foreach (DbValidationError error in validationResult.ValidationErrors)
{
errorMessages.Add(entityName + "." + error.PropertyName + ": " + error.ErrorMessage);
}
}
답변
EntityValidationErrors
컬렉션 을 보려면 다음 Watch 식을 Watch 창에 추가하십시오.
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors
Visual Studio 2013을 사용하고 있습니다.
답변
catch {...}
블록 내에서 디버그 모드에있는 동안 “QuickWatch”창 ( ctrl+ alt+ q)을 열고 여기에 붙여 넣으십시오.
((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors
그러면 ValidationErrors
트리 로 드릴 다운 할 수 있습니다 . 이 오류에 대한 즉각적인 통찰력을 얻는 가장 쉬운 방법입니다.
첫 번째 오류 만 신경 쓰고 catch
블록 이없는 Visual 2012+ 사용자의 경우 다음을 수행 할 수도 있습니다.
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage
답변
디버깅 중 오류를 검사하여 의미있는 오류 메시지를 빠르게 찾으려면 다음을 수행하십시오.
-
다음에 대한 빠른 시계 추가 :
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors
-
다음과 같이 EntityValidationErrors로 드릴 다운하십시오.
(수집 항목 예 : [0])> ValidationErrors> (수집 항목 예 : [0])> ErrorMessage
답변
실제로 이것은 검증 문제 일 뿐이므로 EF는 데이터베이스를 변경하기 전에 먼저 엔티티 특성을 검증합니다. 따라서 EF는 테이블을 디자인 할 때와 같이 속성 값이 범위를 벗어 났는지 확인합니다. Table_Column_UserName은 varchar (20)입니다. 그러나 EF에서 20보다 긴 값을 입력했습니다. 또는 다른 경우 열이 널이 될 수없는 경우. 따라서 유효성 검사 프로세스에서 변경 여부에 관계없이 값을 null이 아닌 열로 설정해야합니다. 나는 개인적으로 Leniel Macaferi 답변과 같습니다. 유효성 검사 문제의 세부 정보를 보여줄 수 있습니다
답변
“실제 유효성 검사 오류”에 중요한 정보가 포함되어있을 수 있으며 이것이 Microsoft가 다른 위치 (속성)에 정보를 싣는 이유 일 수 있습니다. 여기에 표시된 해결책은 실용적이지만주의해서 사용해야합니다.
확장 방법을 만들고 싶습니다. 더 많은 이유 :
- 원본 스택 추적 유지
- 개방 / 폐쇄 원칙을 따릅니다 (예 : 다른 종류의 로그에 다른 메시지를 사용할 수 있음)
- 프로덕션 환경에는 DbEntityValidationException이 발생할 수있는 다른 위치 (예 : 다른 dbcontext)가있을 수 있습니다.
