EF 4.1 용 DatabaseInitializer ()에서 모델을 초기화 하고이 성가신 오류가 발생 "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."
하는 상황이 있으므로이 EntityValidationErrors로 이동 {System.Data.Entity.Validation.DbEntityValidationResult}
하여 초기화 할 수없는 필드에 대한 정보를 전혀 제공하지 않는 필드가 있습니다. . 이 오류에 대한 자세한 정보를 얻을 수있는 방법이 있습니까?
사물을 지우려면 :
문자열 길이 문제를 해결하는 방법을 알고 있습니다. 내가 묻는 것은 모델을 깨뜨리는 정확한 필드 이름을 얻는 방법입니다.
답변
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
답변
try / catch 블록에서 시도해 볼 수 있습니까?
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
답변
내 생각에 가장 좋은 해결책은 이러한 종류의 오류를 중앙 집중식으로 처리하는 것입니다.
이 메소드를 기본 DbContext
클래스에 추가하십시오 .
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
throw new DbEntityValidationException(errorMessages);
}
}
컨텍스트의 SaveChanges()
메서드를 덮어 쓰고 모든 엔터티 유효성 검사 오류가 포함 된 쉼표로 구분 된 목록이 표시됩니다.
이것이 도움이되기를 바랍니다.
답변
글쎄, 나는 같은 문제가 있었다. 내 모델은 EF CTP5에서 잘 작동했지만 초기화하려고 할 때 “하나 이상의 엔터티에 대한 유효성 검사에 실패했습니다”라는 오류와 함께 4.1에서 빌드하지 못했습니다.
public string Comment {get; set;}
그런 다음 재정의 된 이니셜 라이저의 시드 방법에서 꽤 긴 (약 600 자) 주석이있었습니다.
요점은 다음과 같습니다. EF 4.1 에서는 경우에 따라 데이터 주석을 명시 적으로 설정 해야 합니다. 나를 위해 설정 :
[StringLength(4000)]
public string Comment {get; set;}
도와주었습니다. CTP5에 아무런 문제가 없었기 때문에 이상합니다.
답변
EntityValidationErrors를 더 읽기 쉽게 만드는 SaveChanges 래퍼를 만드는 것이 유용하다는 것을 알았습니다.
Public Sub SaveChanges(entities As Entities)
Try
entities.SaveChanges()
Catch ex As DbEntityValidationException
Dim msg As New StringBuilder
msg.AppendLine(ex.Message)
For Each vr As DbEntityValidationResult In ex.EntityValidationErrors
For Each ve As DbValidationError In vr.ValidationErrors
msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage))
Next
Next
Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex)
End Try
End Sub
그런 다음 전체 프로젝트에서 ‘entities.SaveChanges ()’를 ‘SaveChanges (entities)’로 변경했습니다.
답변
나는 그것이 오래된 질문이라는 것을 알고 있지만 여기 내 대답이 있습니다.
catch (DbEntityValidationException ex)
{
String.Join("\n", ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage)
.ToArray());
}
코드를 먼저 사용하는 경우 여러 리소스 파일을 사용하여 오류 메시지를 전역화할 수도 있습니다.
예를 들어이 두 개의 별도 리소스 파일 (오류 및 속성 이름)이 있으며 다음과 같이 사용합니다.
public class Person
{
[Required(ErrorMessageResourceName = "required",ErrorMessageResourceType =typeof(ErrorMessages))]
[MaxLength(100,ErrorMessageResourceName = "maxLength", ErrorMessageResourceType = typeof(ErrorMessages))]
[Display(Name = "FirstName",ResourceType = typeof(Properties))]
public string FirstName { get; set; }
}
보시다시피 속성 이름을 포함하여 오류 메시지를 완전히 번역 했으므로 나중에 예를 들어 사용자에서 사용할 수 있습니다.