La solución más fácil es anular SaveChanges
en su clase de entidades. Puede capturar DbEntityValidationException
, desenvolver los errores reales y crear uno nuevo DbEntityValidationException
con el mensaje mejorado.
- Cree una clase parcial al lado de su archivo SomethingSomething.Context.cs.
- Usa el código al final de esta publicación.
- Eso es. Su implementación utilizará automáticamente los SaveChanges reemplazados sin ningún trabajo de refactorización.
Su mensaje de excepción ahora se verá así:
System.Data.Entity.Validation.DbEntityValidationException: la validación falló para una o más entidades. Consulte la propiedad 'EntityValidationErrors' para obtener más detalles. Los errores de validación son: El campo PhoneNumber debe ser una cadena o tipo de matriz con una longitud máxima de '12'; El campo Apellido es obligatorio.
Puede descartar los SaveChanges anulados en cualquier clase que herede de 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);
}
}
}
El DbEntityValidationException
también contiene las entidades que causaron los errores de validación. Entonces, si necesita aún más información, puede cambiar el código anterior para generar información sobre estas entidades.
Ver también: http://devillers.nl/improving-dbentityvalidationexception/
using System.Linq;
Como Martin indicó, hay más información en el
DbEntityValidationResult
. Me pareció útil obtener mi nombre de clase POCO y el nombre de la propiedad en cada mensaje, y quería evitar tener que escribirErrorMessage
atributos personalizados en todas mis[Required]
etiquetas solo por esto.El siguiente ajuste al código de Martin se ocupó de estos detalles por mí:
fuente
SelectMany and Aggregate
en github por DaringPara ver la
EntityValidationErrors
colección, agregue la siguiente expresión Watch a la ventana Watch.Estoy usando visual studio 2013
fuente
Mientras está en modo de depuración dentro del
catch {...}
bloque, abra la ventana "QuickWatch" ( ctrl+ alt+ q) y pegue allí:Esto le permitirá profundizar en el
ValidationErrors
árbol. Es la forma más fácil que he encontrado para obtener información instantánea sobre estos errores.Para los usuarios de Visual 2012+ que solo se preocupan por el primer error y pueden no tener un
catch
bloqueo, incluso pueden hacer:fuente
Para encontrar rápidamente un mensaje de error significativo inspeccionando el error durante la depuración:
Agregue un reloj rápido para:
Profundice en EntityValidationErrors como este:
(elemento de colección, por ejemplo, [0])> ValidationErrors> (elemento de colección, por ejemplo, [0])> Mensaje de error
fuente
En realidad, este es solo el problema de validación, EF validará primero las propiedades de la entidad antes de realizar cualquier cambio en la base de datos. Entonces, EF verificará si el valor de la propiedad está fuera de rango, como cuando diseñó la tabla. Table_Column_UserName es varchar (20). Pero, en EF, ingresó un valor superior a 20. O, en otros casos, si la columna no permite ser Nulo. Por lo tanto, en el proceso de validación, debe establecer un valor en la columna no nula, sin importar si va a realizar el cambio en ella. Personalmente, me gusta la respuesta de Leniel Macaferi. Puede mostrarle los detalles de los problemas de validación.
fuente
Creo que "Los errores de validación reales" pueden contener información confidencial, y esta podría ser la razón por la cual Microsoft decidió colocarlos en otro lugar (propiedades). La solución marcada aquí es práctica, pero debe tomarse con precaución.
Preferiría crear un método de extensión. Más razones para esto:
fuente
Para Azure Functions, usamos esta extensión simple para Microsoft.Extensions.Logging.ILogger
y ejemplo de uso:
fuente
Use try block en su código como
Puedes consultar los detalles aquí también
http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/
La validación falló para una o más entidades. Vea la propiedad 'EntityValidationErrors' para más detalles
http://blogs.infosupport.com/improving-dbentityvalidationexception/
fuente