Entidad Framework: “La actualización de la tienda, inserción o eliminación afectó a un número inesperado de filas (0)”.

Estoy usando Entity Framework para poblar un control de cuadrícula. A veces, cuando realizo actualizaciones, aparece el siguiente error:

La actualización, inserción o eliminación de la tienda afectó a un número inesperado de filas (0). Las entidades pueden haber sido modificadas o eliminadas desde que se cargaron las entidades. Actualice las entradas de ObjectStateManager.

No puedo entender cómo reproducir esto. Pero podría tener algo que ver con lo juntos que hago las actualizaciones. ¿Alguien ha visto esto o alguien sabe a qué se refiere el mensaje de error?

Editar: Desafortunadamente, ya no tengo la libertad de reproducir el problema que tenía aquí, porque me alejé de este proyecto y no recuerdo si finalmente encontré una solución, si otro desarrollador lo solucionó, o si trabajé en torno a él. Por lo tanto, no puedo aceptar ninguna respuesta.

Ese es un efecto secundario de una característica llamada concurrencia optimista.

No estoy 100% seguro de cómo activarlo / desactivarlo en Entity Framework, pero básicamente lo que le dice es que, entre cuando retiró los datos de la base de datos y cuando guardó los cambios, alguien más ha cambiado los datos (lo que significaba que cuando se iba) para guardarlo, 0 filas realmente se actualizaron). En términos de SQL, la cláusula where su consulta de update contiene el valor original de cada campo de la fila, y si se ven afectadas 0 filas, sabe que algo salió mal.

La idea detrás de esto es que no terminará sobrescribiendo un cambio que su aplicación no sabía que sucedió; básicamente es una pequeña medida de seguridad introducida por .NET en todas sus actualizaciones.

Si es consistente, las probabilidades están sucediendo dentro de su propia lógica (por ejemplo: en realidad está actualizando los datos usted mismo en otro método entre la selección y la actualización), pero podría ser simplemente una condición de carrera entre dos aplicaciones.

Me encontré con esto y fue causado por el campo de identificación (clave) de la entidad no establecido. Por lo tanto, cuando el contexto fue para guardar los datos, no pudo encontrar un ID = 0. Asegúrese de colocar un punto de interrupción en su statement de actualización y verificar que se haya establecido el ID de la entidad.

Del comentario de Paul Bellora

Tuve este problema exacto, causado al olvidar incluir la entrada de ID oculta en la página de edición .cshtml

Wow, muchas respuestas, pero obtuve este error cuando hice algo ligeramente diferente que ningún otro ha mencionado.

Para abreviar, si crea un objeto nuevo y le dice a EF que se modificó usando EntityState.Modified , arrojará este error ya que aún no existe en la base de datos. Aquí está mi código:

 MyObject foo = new MyObject() { someAttribute = someValue }; context.Entry(foo).State = EntityState.Modified; context.SaveChanges(); 

Sí, esto parece tonto, pero surgió porque el método en cuestión solía pasar a ser creado anteriormente, ahora solo tiene someValue pasado y crea foo .

EntityState.Modified fácil, simplemente cambie EntityState.Modified a EntityState.Added o cambie esa línea completa a:

 context.MyObject.Add(foo); 

Estaba enfrentando este mismo error de asustar … 🙂 Entonces me di cuenta de que me estaba olvidando de establecer un

@Html.HiddenFor(model => model.UserProfile.UserId)

para la clave principal del objeto que se está actualizando ¡Tiendo a olvidar esta cosa simple, pero muy importante!

Por cierto: HiddenFor es para ASP.NET MVC.

Compruebe si olvidó el atributo “DataKeyNames” en GridView. es imprescindible cuando se modifican datos dentro de GridView

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx

El problema es causado por una de estas dos cosas:

  1. Intentó actualizar una fila con una o más propiedades, el Concurrency Mode: Fixed … y la Concurrencia Optimista evitó que se guardaran los datos. Es decir. algunos cambiaron los datos de la fila entre el momento en que recibió los datos del servidor y cuando guardó los datos del servidor.
  2. Intentó actualizar o eliminar una fila, pero la fila no existe. Otro ejemplo de alguien que cambia los datos (en este caso, eliminando) entre una recuperación y luego guarda O está en lo cierto tratando de actualizar un campo que no es una Identidad (es decir, StoreGeneratedPattern = Computed ) y esa fila no existe .

Estaba teniendo el mismo problema y la respuesta de @ webtrifusion ayudó a encontrar la solución.

Mi modelo estaba usando el atributo Bind(Exclude) en la identificación de la entidad que causaba que el valor de la ID de la entidad fuera cero en HttpPost.

 namespace OrderUp.Models { [Bind(Exclude = "OrderID")] public class Order { [ScaffoldColumn(false)] public int OrderID { get; set; } [ScaffoldColumn(false)] public System.DateTime OrderDate { get; set; } [Required(ErrorMessage = "Name is required")] public string Username { get; set; } } } 

Obtuve el mismo error porque parte del PK era una columna de fecha y hora, y el registro que se insertaba usaba DateTime.Now como el valor para esa columna. El marco de la entidad insertaría el valor con precisión de milisegundos, y luego buscaría el valor que acaba de insertar también con una precisión de milisegundos. Sin embargo, SqlServer había redondeado el valor a la segunda precisión y, por lo tanto, el marco de entidades no pudo encontrar el valor de precisión de milisegundos.

La solución fue truncar los milisegundos de DateTime.Now antes de insertar.

tuve el mismo problema, me di cuenta de que fue causado por RowVersion que fue nulo. Verifique que su Id y su RowVersion no sean nulos .

para más información, consulte este tutorial

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

Mientras edita, incluya el id o la clave principal de la entidad como un campo oculto en la vista

es decir

  @Html.HiddenFor(m => m.Id) 

eso resuelve el problema

Además, si su modelo incluye un artículo no usado, inclúyalo también y publíquelo en el controlador

Necesita incluir explícitamente un BoundField de la clave principal. Si no desea que el usuario vea la clave principal, debe ocultarla a través de css:

   

Donde ‘oculto’ es una clase en CSS que tiene su pantalla configurada en ‘ninguna’.

También encontré este error. El problema que resultó fue causado por un Disparador en la mesa en el que intentaba guardar. El disparador usó ‘INSTEAD OF INSERT’, lo que significa 0 filas que alguna vez se insertaron en esa tabla, de ahí el error. Afortunadamente, en el caso de que la funcionalidad del disparador fuera incorrecta, supongo que podría ser una operación válida que debería manejarse de alguna manera en el código. Espero que esto ayude a alguien algún día.

Empecé a recibir este error después de cambiar de modelo primero a código primero. Tengo varios hilos actualizando una base de datos donde algunos pueden actualizar la misma fila. No sé por qué no tuve problemas para usar el modelo primero, supongo que usa un valor predeterminado de simultaneidad diferente.

Para manejarlo en un lugar sabiendo las condiciones bajo las cuales podría ocurrir, agregué la siguiente sobrecarga a mi clase DbContext:

 using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; public class MyDbContext: DbContext { ... public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) { try { return SaveChanges(); } catch (DbUpdateConcurrencyException ex) { foreach (DbEntityEntry entry in ex.Entries) { if (refreshMode == RefreshMode.ClientWins) entry.OriginalValues.SetValues(entry.GetDatabaseValues()); else entry.Reload(); } return SaveChanges(); } } } 

Luego llamado SaveChanges(true) donde corresponda.

  @Html.HiddenFor(model => model.RowVersion) 

Mi versión de row era nula, así que tuve que agregar esto a la vista que resolvió mi problema

La línea [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)] funcionó en mi caso:

 using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int? SomeNumber { get; set; } 

Solo asegúrese de que la tabla y el formulario tengan la clave principal y edmx actualizados.

encontré que cualquier error durante la actualización generalmente se debió a: – No hay clave principal en la Tabla – No hay clave primaria en Editar vista / formulario (por ejemplo, @Html.HiddenFor(m=>m.Id )

Obtuve este error esporádicamente cuando uso un método async . No ha sucedido desde que cambié a un método sincrónico.

Errores esporádicamente

 [Authorize(Roles = "Admin")] [HttpDelete] [Route("file/{id}/{customerId}/")] public async Task Delete(int id, int customerId) { var file = new Models.File() { Id = id, CustomerId = customerId }; db.Files.Attach(file); db.Files.Remove(file); await db.SaveChangesAsync(); return Ok(); } 

Funciona todo el tiempo:

 [Authorize(Roles = "Admin")] [HttpDelete] [Route("file/{id}/{customerId}/")] public IHttpActionResult Delete(int id, int customerId) { var file = new Models.File() { Id = id, CustomerId = customerId }; db.Files.Attach(file); db.Files.Remove(file); db.SaveChanges(); return Ok(); } 

Obtuve ese error cuando borré algunas filas en la base de datos (en el ciclo) y agregué las nuevas en la misma tabla.

Las soluciones para mí fueron crear dinámicamente un nuevo contexto en cada iteración de ciclo

  public void Save(object entity) { using (var transaction = Connection.BeginTransaction()) { try { SaveChanges(); transaction.Commit(); } catch (OptimisticConcurrencyException) { if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified) this.Refresh(RefreshMode.StoreWins, entity); else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added) Detach(entity); AcceptAllChanges(); transaction.Commit(); } } } 

Yo tuve el mismo problema. En mi caso, estaba tratando de actualizar la clave principal, lo cual no está permitido.

Si está intentando crear una asignación en su archivo edmx a una “función Importaciones”, esto puede dar como resultado este error. Simplemente borre los campos para insertar, actualizar y eliminar que se encuentran en Detalles de mapeo para una entidad dada en su edmx, y debería funcionar. Espero haber dejado en claro.

También tuve este error. Hay algunas situaciones en las que la Entidad puede no estar al tanto del Contexto de la Base de Datos real que está utilizando o el Modelo puede ser diferente. Para esto, establece: EntityState.Modified; a EntityState.Added;

Para hacer esto:

 if (ModelState.IsValid) { context.Entry(yourModelReference).State = EntityState.Added; context.SaveChanges(); } 

Esto asegurará que la Entidad sepa que está usando o agregando el Estado con el que está trabajando. En este punto, se deben establecer todos los valores correctos del modelo. Tenga cuidado de no perder ningún cambio que se haya realizado en el fondo.

Espero que esto ayude.

Esto también ocurrirá si está intentando insertar en una situación de restricción única, es decir, si solo puede tener un tipo de dirección por empleador e intenta insertar un segundo del mismo tipo con el mismo empleador, obtendrá el mismo problema .

O

Esto también podría ocurrir si todas las propiedades del objeto que fueron asignadas a, fueron asignados con los mismos valores que tenían antes.

  using(var db = new MyContext()) { var address = db.Addresses.FirstOrDefault(x => x.Id == Id); address.StreetAddress = StreetAddress; // if you are assigning address.City = City; // all of the same values address.State = State; // as they are address.ZipCode = ZipCode; // in the database db.SaveChanges(); // Then this will throw that exception } 

Bueno, tengo este mismo problema. Pero esto fue debido a mi propio error. En realidad estaba guardando un objeto en lugar de agregarlo. Entonces este era el conflicto.

Una forma de solucionar este problema en un entorno de servidor Sql es utilizar el Sql Profiler incluido con su copia de SqlServer, o si utiliza la versión Express, obtenga una copia de Express Profiler gratis de CodePlex mediante el siguiente enlace:

Express Profiler

Al usar Sql Profiler puede tener acceso a lo que sea enviado por EF a la base de datos. En mi caso, esto ascendió a:

 exec sp_executesql N'UPDATE [dbo].[Category] SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3 WHERE ([CategoryID] = @4) ',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier', @0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09', @3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778' go 

Copié esto pegado en una ventana de consulta en el Servidor Sql y lo ejecuté. Efectivamente, aunque se ejecutó, 0 registros se vieron afectados por esta consulta, por lo tanto, el error fue devuelto por EF.

En mi caso, el problema fue causado por el CategoryID.

No se identificó el ID de categoría por el ID EF enviado a la base de datos, por lo tanto, se afectaron 0 registros.

Sin embargo, esto no fue culpa de EF, sino más bien un buggy nulo coalescente “?? statement en un controlador de vista que estaba enviando tonterías al nivel de datos.

Ninguna de las respuestas anteriores cubrió por completo mi situación y la solución a la misma.

Código donde se produjo el error en el controlador MVC5:

  if (ModelState.IsValid) { db.Entry(object).State = EntityState.Modified; db.SaveChanges(); // line that threw exception return RedirectToAction("Index"); } 

Recibí esta excepción cuando estaba guardando un objeto en una vista Editar. La razón por la que lo arrojó fue porque cuando volví a guardarlo, modifiqué las propiedades que formaban la clave principal en el objeto. Por lo tanto, establecer su estado en Modificado no tenía ningún sentido para EF: era una entrada nueva, no una previamente guardada.

Puede resolver esto ya sea por A) modificando la llamada guardada para Agregar el objeto, o B) simplemente no cambia la clave primaria en la edición. Hice B).

Me encontré con este problema en una tabla que le faltaba una clave principal y tenía una columna DATETIME (2, 3) (por lo que la “clave principal” de la entidad era una combinación de todas las columnas) … Al realizar la inserción, la marca de tiempo tenía un tiempo más preciso (2018-03-20 08: 29: 51.8319154) que se truncó a (2018-03-20 08: 29: 51.832) por lo que la búsqueda en los campos clave falla.

Me encontré con esto usando Telerik’s RadGrid. Tenía la clave principal como columna de malla que estaba configurada para solo lectura. Funcionaría bien si la columna fuera display = “false” pero readonly = “true” causó el problema. Lo resolví haciendo que la columna de la cuadrícula mostrara = falso y agregué una columna de plantilla separada para mostrar

        

Obtuve esta excepción al adjuntar un objeto que no existía en la base de datos. Supuse que el objeto se cargó desde un contexto diferente, pero si era la primera vez que el usuario visitaba el sitio, el objeto se creó desde cero. Tenemos claves primarias autoincrementadas, por lo que podría reemplazar

 context.Users.Attach(orderer); 

con

 if (orderer.Id > 0) { context.Users.Attach(orderer); } 

Esto puede suceder si intenta actualizar un registro con un Id que no existe en la base de datos.