[C#] DbEntityValidationException-오류의 원인을 쉽게 알 수있는 방법은 무엇입니까?

Entity Framework를 사용하는 프로젝트가 있습니다. SaveChanges내 전화하는 동안 DbContext다음 예외가 발생합니다.

System.Data.Entity.Validation.DbEntityValidationException : 하나 이상의 엔티티에 대한 유효성 검증에 실패했습니다. 자세한 내용은 ‘EntityValidationErrors’속성을 참조하십시오.

이것은 모두 훌륭하고 멋지지만이 예외가 발생할 때마다 디버거를 연결하고 싶지 않습니다. 또한 프로덕션 환경에서는 디버거를 쉽게 연결할 수 없으므로 이러한 오류를 재현하기 위해 많은 시간을 투자해야합니다.

안에 숨겨진 세부 정보를 어떻게 볼 수 DbEntityValidationException있습니까?



답변

가장 쉬운 해결책은 SaveChanges엔터티 클래스 에서 재정의 하는 것입니다. 을 포착하고 DbEntityValidationException실제 오류를 풀고 DbEntityValidationException개선 된 메시지 로 새 메시지를 작성할 수 있습니다 .

  1. SomethingSomething.Context.cs 파일 옆에 부분 클래스를 작성하십시오.
  2. 이 게시물의 맨 아래에있는 코드를 사용하십시오.
  3. 그게 다야. 구현시 리팩터링 작업없이 재정의 된 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)가있을 수 있습니다.