update tutorial registro que insertar framework first español datos crear contexto conexion con code agregar c# sql asp.net-mvc entity-framework code-first

tutorial - que es entity framework c#



La validación falló para una o más entidades al guardar los cambios en la base de datos de SQL Server utilizando Entity Framework (16)

Aquí hay una extensión de la extensión de Tony ... :-)

Para Entity Framework 4.x, si desea obtener el nombre y el valor del campo clave para saber qué instancia de entidad (registro DB) tiene el problema, puede agregar lo siguiente. Esto proporciona acceso a los miembros de la clase ObjectContext más poderosos desde su objeto DbContext.

// Get the key field name & value. // This assumes your DbContext object is "_context", and that it is a single part key. var e = ((IObjectContextAdapter)_context).ObjectContext.ObjectStateManager.GetObjectStateEntry(validationErrors.Entry.Entity); string key = e.EntityKey.EntityKeyValues[0].Key; string val = e.EntityKey.EntityKeyValues[0].Value;

Quiero guardar mi Editar en la base de datos y estoy usando Entity FrameWork Code-First en ASP.NET MVC 3 / C # pero estoy recibiendo errores. En mi clase de evento, tengo tipos de datos DateTime y TimeSpan pero en mi base de datos, tengo fecha y hora respectivamente. Podría ser ésta la razón? ¿Cómo puedo convertir al tipo de datos apropiado en el código antes de guardar los cambios en la base de datos?

public class Event { public int EventId { get; set; } public int CategoryId { get; set; } public int PlaceId { get; set; } public string Title { get; set; } public decimal Price { get; set; } public DateTime EventDate { get; set; } public TimeSpan StartTime { get; set; } public TimeSpan EndTime { get; set; } public string Description { get; set; } public string EventPlaceUrl { get; set; } public Category Category { get; set; } public Place Place { get; set; } }

Método en el controlador >>>> Problema en storeDB.SaveChanges ();

// POST: /EventManager/Edit/386 [HttpPost] public ActionResult Edit(int id, FormCollection collection) { var theEvent = storeDB.Events.Find(id); if (TryUpdateModel(theEvent)) { storeDB.SaveChanges(); return RedirectToAction("Index"); } else { ViewBag.Categories = storeDB.Categories.OrderBy(g => g.Name).ToList(); ViewBag.Places = storeDB.Places.OrderBy(a => a.Name).ToList(); return View(theEvent); } }

con

public class EventCalendarEntities : DbContext { public DbSet<Event> Events { get; set; } public DbSet<Category> Categories { get; set; } public DbSet<Place> Places { get; set; } }

Base de datos SQL Server 2008 R2 / T-SQL

EventDate (Datatype = date) StartTime (Datatype = time) EndTime (Datatype = time)

Formulario HTTP

EventDate (Datatype = DateTime) e.g. 4/8/2011 12:00:00 AM StartTime (Datatype = Timespan/time not sure) e.g. 08:30:00 EndTime (Datatype = Timespan/time not sure) e.g. 09:00:00

Error del servidor en la aplicación ''/''.

La validación falló para una o más entidades. Vea la propiedad ''EntityValidationErrors'' para más detalles.

Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.Data.Entity.Validation.DbEntityValidationException: La validación falló para una o más entidades. Vea la propiedad ''EntityValidationErrors'' para más detalles.

Error de fuente:

Line 75: if (TryUpdateModel(theEvent)) Line 76: { Line 77: storeDB.SaveChanges(); Line 78: return RedirectToAction("Index"); Line 79: }

Archivo de origen: C: / sep / MvcEventCalendar / MvcEventCalendar / Controllers / EventManagerController.cs Línea: 77

Traza de la pila:

[DbEntityValidationException: la validación falló para una o más entidades. Vea la propiedad ''EntityValidationErrors'' para más detalles.]


Asegúrese de que si tiene nvarchar (50) en la fila DB no intente insertar más de 50 caracteres en ella. Error estúpido, pero me tomó 3 horas para averiguarlo.


Como una mejora tanto para Praveen como para Tony, uso una anulación:

public partial class MyDatabaseEntities : DbContext { public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException dbEx) { foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}", validationErrors.Entry.Entity.GetType().FullName, validationError.PropertyName, validationError.ErrorMessage); } } throw; // You can also choose to handle the exception here... } } }


Creo que agregar try / catch para cada operación SaveChanges() no es una buena práctica, es mejor centralizar esto:

Agregue esta clase a la clase principal de 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.ErrorMessage)); throw new DbEntityValidationException(errorMessages); } }

Esto sobrescribirá el método SaveChanges() su contexto y obtendrá una lista separada por comas que contiene todos los errores de validación de la entidad.

Esto también puede mejorarse, para registrar errores en la producción env, en lugar de simplemente lanzar un error.

Espero que esto sea de ayuda.


En el caso de que tenga clases con los mismos nombres de propiedades, aquí hay una pequeña extensión de la respuesta de Praveen:

catch (DbEntityValidationException dbEx) { foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { Trace.TraceInformation( "Class: {0}, Property: {1}, Error: {2}", validationErrors.Entry.Entity.GetType().FullName, validationError.PropertyName, validationError.ErrorMessage); } } }


Esta implementación envuelve la excepción de excepción a excepción con texto detallado. Maneja DbEntityValidationException , DbUpdateException , errores de rango de datetime2 (MS SQL) e incluye la clave de la entidad no válida en el mensaje (útil cuando se guardan muchas entidades en una llamada de SaveChanges ).

Primero, anule SaveChanges en la clase DbContext:

public class AppDbContext : DbContext { public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException dbEntityValidationException) { throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException); } catch (DbUpdateException dbUpdateException) { throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException); } } public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken) { try { return await base.SaveChangesAsync(cancellationToken); } catch (DbEntityValidationException dbEntityValidationException) { throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException); } catch (DbUpdateException dbUpdateException) { throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException); } }

Clase ExceptionHelper:

public class ExceptionHelper { public static Exception CreateFromEntityValidation(DbEntityValidationException ex) { return new Exception(GetDbEntityValidationMessage(ex), ex); } public static string GetDbEntityValidationMessage(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); return exceptionMessage; } public static IEnumerable<Exception> GetInners(Exception ex) { for (Exception e = ex; e != null; e = e.InnerException) yield return e; } public static Exception CreateFromDbUpdateException(DbUpdateException dbUpdateException) { var inner = GetInners(dbUpdateException).Last(); string message = ""; int i = 1; foreach (var entry in dbUpdateException.Entries) { var entry1 = entry; var obj = entry1.CurrentValues.ToObject(); var type = obj.GetType(); var propertyNames = entry1.CurrentValues.PropertyNames.Where(x => inner.Message.Contains(x)).ToList(); // check MS SQL datetime2 error if (inner.Message.Contains("datetime2")) { var propertyNames2 = from x in type.GetProperties() where x.PropertyType == typeof(DateTime) || x.PropertyType == typeof(DateTime?) select x.Name; propertyNames.AddRange(propertyNames2); } message += "Entry " + i++ + " " + type.Name + ": " + string.Join("; ", propertyNames.Select(x => string.Format("''{0}'' = ''{1}''", x, entry1.CurrentValues[x]))); } return new Exception(message, dbUpdateException); } }


Este código me ayudó a encontrar mi problema cuando tuve un problema con mi Entidad VAlidation Erros. Me dijo el problema exacto con mi definición de entidad. Intente seguir el código donde necesita cubrir storeDB.SaveChanges (); en el siguiente bloque intento de captura.

try { if (TryUpdateModel(theEvent)) { storeDB.SaveChanges(); return RedirectToAction("Index"); } } catch (System.Data.Entity.Validation.DbEntityValidationException dbEx) { Exception raise = dbEx; foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { string message = string.Format("{0}:{1}", validationErrors.Entry.Entity.ToString(), validationError.ErrorMessage); // raise a new exception nesting // the current instance as InnerException raise = new InvalidOperationException(message, raise); } } throw raise; }


Este error también ocurre cuando intenta guardar una entidad que tiene errores de validación. Una buena manera de hacer esto es olvidarse de revisar ModelState.IsValid antes de guardar en su base de datos.


Esto podría deberse a la cantidad máxima de caracteres permitidos para una columna específica, como en sql, un campo podría tener el tipo de datos siguiente nvarchar(5) pero la cantidad de caracteres ingresados ​​por el usuario es mayor que la especificada, por lo que surge el error.


Gracias por sus respuestas, me ayudó mucho. Al codificar en Vb.Net, este código Bolt para Vb.Net

Try Return MyBase.SaveChanges() Catch dbEx As Validation.DbEntityValidationException For Each [error] In From validationErrors In dbEx.EntityValidationErrors From validationError In validationErrors.ValidationErrors Select New With { .PropertyName = validationError.PropertyName, .ErrorMessage = validationError.ErrorMessage, .ClassFullName = validationErrors.Entry.Entity .GetType().FullName} Diagnostics.Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}", [error].ClassFullName, [error].PropertyName, [error].ErrorMessage) Next Throw End Try


Me enfrenté al mismo problema hace un par de días al actualizar la base de datos. En mi caso, se agregaron pocas columnas no anulables nuevas para mantenimiento que no se proporcionaron en el código que está causando la excepción. Entiendo esos campos y valores suministrados para ellos y su resuelto.


No me gustan las excepciones. Registré OnSaveChanges y tengo esto.

var validationErrors = model.GetValidationErrors(); var h = validationErrors.SelectMany(x => x.ValidationErrors .Select(f => "Entity: " +(x.Entry.Entity) + " : " + f.PropertyName + "->" + f.ErrorMessage));


Puede extraer toda la información de la DbEntityValidationException con el siguiente código (debe agregar los espacios de nombres: System.Data.Entity.Validation y System.Diagnostics a su lista de using ):

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); } } }


Recibí este error hoy y no pude resolverlo por un tiempo, pero me di cuenta de que era después de agregar algunos RequireAttribute s a mis modelos y que algunos datos de semilla de desarrollo no estaban RequireAttribute todos los campos requeridos.
Entonces, solo tenga en cuenta que si obtiene este error al actualizar la base de datos a través de algún tipo de estrategia de inicio como DropCreateDatabaseIfModelChanges , debe asegurarse de que sus datos iniciales cumplan y satisfagan los atributos de validación de datos del modelo .

Sé que esto es un poco diferente al problema en la pregunta, pero es una pregunta popular, así que pensé que agregaría un poco más a la respuesta para otros que tienen el mismo problema que yo.
Espero que esto ayude a otros :)


puede ser causada por la propiedad que no está rellenada por el modelo ... en su lugar está rellena por el controlador ... lo que puede causar este error. La solución a esto es asignar la propiedad antes de aplicar la validación de ModelState. y esta segunda asunción es. es posible que ya tenga datos en su base de datos e intente actualizarlos, pero ahora los está buscando.


No se requiere cambio de código:

Mientras está en el modo de depuración dentro del bloque catch {...} , abra la ventana "QuickWatch" ( Ctrl + Alt + Q ) y péguelo allí:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

o:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

Si no está en un try / catch o no tiene acceso al objeto de excepción.

Esto le permitirá profundizar en el árbol de ValidationErrors . Es la forma más fácil que he encontrado para obtener una visión instantánea de estos errores.