Mi proyecto usa EF (probado con la versión 4 usando la plantilla de seguimiento automático y con la versión 5 usando las plantillas predeterminadas, todas las bases de datos primero) contra SQL Server 2012. Las tablas de la base de datos tienen cada una una rowversion
( timestamp
) definida.
Utilizando EF en su núcleo, lo que significa que mi código en las actualizaciones de la base de datos parece:
using (var db = new MyContext())
{
//db.Entry(myInstance).State = EntityState.Modified;
db.SaveChanges();
}
no rowversion
ninguna alerta de rowversion
. Ejecuto clientes paralelos, cada uno lee el mismo registro, lo modifica y luego lo escribe en la base de datos. Se aceptan todas las actualizaciones, no se aplica concurrencia.
¿Tengo que trabajar con procedimientos almacenados para mis comandos de actualización (con una cláusula where que indica mi valor de rowversion
) para que EF reconozca la concurrencia "incorporada" o hay rowversion
otra forma (configuración, llamadas a métodos específicos) para hacer mi código? ¿trabajo?
RowVersion
(o el tipo de campo TimeStamp
) en SQL
es un campo como cualquier otro (excepto por ser obligatorio y auto-incrementable). Existe un manejo de base de datos específico de su valor en las actualizaciones (es decir, incrementándolo), pero no hay un manejo de base de datos específico que compare su valor antes de la actualización. EF
en el otro lado le permite definir ConcurrencyMode
para cada campo ( edmx
). Si lo desea, puede marcar todos sus campos con ConcurrencyMode=Fix
(en lugar del valor predeterminado None
), e incluirlos todos dentro de la cláusula where de la actualización (comparando los valores originales de la entidad con los valores actuales del registro en la base de datos) . Pero es más fácil establecer un campo por entidad, es decir, el campo RowVersion
, con ese modo. Sobre todo porque la única parte que lo mantiene para usted es la base de datos. System.Data.OptimisticConcurrencyException
. Aún debe mantenerse alejado de los flujos de trabajo de EF
que manipulan sus conjuntos de objetos, como el uso de myObjectSet.Attach(myEntity)
, que realiza un viaje a la base de datos para obtener los datos actuales y fusiona sus cambios en ellos. Debido a que el campo RowVersion
normalmente no se modifica, la actualización se activará con el valor actual de la base de datos y no generará la excepción de concurrencia.