c# - Linq fila no encontrada o cambiada
asp.net linq-to-sql (8)
A veces es realmente simple ... Asegúrate de que no haya cerraduras en la mesa. En mi caso, la interfaz de usuario de SQL Server Management Studio tenía bloqueos que no conocía (no recordaba) mientras realizaba la depuración. Al descargarlo se borraron esos bloqueos y las cosas empezaron a funcionar de nuevo.
Error Message: Row not found or changed.
Stack Trace:
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
Esto ocurre aparentemente al azar. Me envían estos errores por correo electrónico, y la URL reportada siempre parece funcionar para mí y debería estar funcionando para todos los demás también.
Puedo arreglar este error por:
- Ir a mi diseño de
dbml
- Seleccionando cada campo en la tabla causando conflictos
- Haga clic derecho y establezca la propiedad
Update Check
enNever
Esto parece evitar que estos tipos de errores sean lanzados.
Sin embargo, es difícil recordar seguir haciendo esto siempre que tenga la oportunidad de dmbl
, agregar nuevas tablas, etc. ¿Hay una mejor manera de resolver este problema? Estoy obteniendo tal vez 50-100 de estos por día, lo que es malo para mis visitantes.
Cada vez que veo este error, significa que algo cambió en la base de datos entre el momento en que cargué el registro / objeto / lo que sea y cuando intenté guardarlo. Sin falta, fue porque mi unidad de trabajo era demasiado grande.
No sé la naturaleza exacta de su aplicación, pero supongo que está creando un contexto de datos, cargando un registro o lista de registros, realizando algunas operaciones en él, consumiendo tiempo y ciclos de procesador, y luego Termine intentando guardar los datos modificados de nuevo en la base de datos. Tal vez incluso cargando una instancia de un registro / objeto y almacenándola en una variable de clase por un tiempo, y luego al final de una página cargando o subproceso o lo que sea que intente guardar algo que haya cambiado. El problema es que debido a que LINQ almacenó una copia de eso, esa es la copia que desea actualizar. Si los datos subyacentes cambian mientras tanto, se vuelve loco.
Pregúntese esto, qué sucede si coloca una transacción de bloqueo en sus datos durante toda la vida útil de sus objetos. Diga que cualquier cosa que cargue puede modificar, nadie más podrá tocarla durante ese tiempo. Básicamente ese es el supuesto aquí. Por supuesto, LINQ es un poco más optimista al respecto, no tiene sentido bloquear la fila o la tabla si es posible que nunca esté actualizando los datos, pero piensa en esos problemas. Pregúntese qué se rompería o ralentizaría significativamente si tuviera que poner estrictos bloqueos transaccionales en sus objetos, y eso probablemente le indicará el código ofensivo.
Mi solución a esto es mantener mi unidad de trabajo lo más pequeña posible. No cargue el objeto, úselo como copia de trabajo y guárdelo en la base de datos, todo en un contexto. En su lugar, cargue el objeto y saque la información que necesita en un solo paso, luego descubra los cambios que necesita aplicar y luego cargue / actualice / guarde el objeto. Seguro que causa más viajes de ida y vuelta a la base de datos, pero le da una mejor seguridad de que está trabajando con la última copia de datos. Seguirá siendo "el último en ganar", lo que significa que si alguien hizo una actualización mientras estaba trabajando con los datos, puede perderlos, pero eso siempre es un riesgo a menos que bloquee el registro con una transacción. Sin embargo, le ofrece la flexibilidad de que si alguien más está modificando campos no relacionados en la misma fila, ambos pueden operar juntos en esos datos.
Esto también puede suceder si un activador de la base de datos cambia cualquier columna en una fila que está actualizando, incluso si no está actualizando esa columna en particular.
Tendrá que volver a verificar que cualquiera de las tablas afectadas en su unidad de trabajo no tenga activadores. Si está utilizando activadores de actualización, entonces probablemente querrá asegurarse de que las columnas actualizadas sean NeverCheck .
GetTable (). Attach (newEntity, originalEntity);
Si no está utilizando un campo de versión para actualizar, el método anterior parametriza los nuevos detalles y las antiguas entidades de los detalles, si la entidad original se modifica en este punto, todavía obtendrá el mismo error, esto depende de usted. Esto funciona como un amuleto, lo he intentado.
Recibí este error en Windows Phone 8. Y me tomó un tiempo descubrir cuál era el problema. Básicamente fue esto:
Tuve una clase llamada TrackingInformation. 1. Desde un servidor obtuve una versión actualizada de él. 2. Mi TileService actualizó el mosaico secundario con su información y (!!) actualizó 1 propiedad y lo guardó en la base de datos local del teléfono. 3. Intenté volver a guardar la primera instancia del objeto y aquí obtuve el error "fila no encontrada o cambiada".
Para mí, solo tuve que quitar la tercera parte y funcionó bien (ya estaba guardado con la versión actualizada). Pero como una propiedad había cambiado, lanzó una excepción ...
No puedo esperar hasta que EF7 llegue a Windows Phone, tanto dolor de cabeza con el actual EF en WP8.
Tuve el mismo problema, y lo resolví comparando dbml con la estructura de db. Una propiedad no estaba configurada como anulable, y eso estaba causando el problema.
Así que compruebe su dbml, y propiedades anulables.
Usando el Analizador de SQL realicé un seguimiento de las transacciones de SQL hacia mi servidor y me di cuenta de que en SubmitChanges()
la instrucción UPDATE
transmitida contiene un valor incorrecto en la cláusula WHERE
. Esto es porque tengo una propiedad que se parece a esto:
class Position{
...
[Column]
public int Pieces{
get{
this.pieces = this.Transformers.Count;
return this.pieces;
}
set{ this.pieces = value; }
}
...
}
Dado que Transformers
es un elemento List<Transformers>
que representa una lista de relaciones Uno a Muchos con otra tabla de Transformers
, tengo que completar manualmente la Lista con cada Transformer
que contenga una clave externa para mi objeto de Position
. Si, por alguna razón, no hago eso, obtendré el error mencionado porque la propiedad Pieces
está sesgada respecto del valor original.
Por lo tanto, la declaración SQL en SubmitChanges()
buscará una entrada WHERE Pieces = somevalue
pero el valor real de Pieces
en la entrada es anothervalue
. Básicamente, LINQ pensará que, mientras tanto, cambió algo en la base de datos, porque la db no devolverá ningún valor a esta solicitud.
Como se dijo, una solución es:
[Column(UpdateCheck=UpdateCheck.Never)]
public int Pieces
{
get {
this.pieces= this.Transformers.Count;
return this.pieces;
}
set { this.pieces= value; }
}
Por supuesto, esto también puede resolverse fácilmente configurando una función getter simple como
getPieces(){
return this.Transformers.Count();
}
y una propiedad "imparcial"
class Position{
...
[Column]
public int Pieces{
get{ return this.pieces; }
set{ this.pieces = value; }
}
...
}
Espero que esto pueda ser de ayuda para alguien. También publico esto porque si alguien más lo hubiera hecho antes, me habría ahorrado horas de mi vida.
actualizar linq a esquema sql en el diseñador resolver problema en mi caso