Simultaneidad optimista en ADO.NET Entity Framework
-
10-07-2019 - |
Pregunta
Encontré un artículo de MSDN que describe cómo EF maneja la concurrencia al guardar los cambios:
Por defecto [...] Object Services guarda el objeto cambios en la base de datos sin comprobando la concurrencia . por propiedades que pueden experimentar una alto grado de concurrencia, nosotros recomendar que la propiedad de la entidad sea definido en la capa conceptual con un atributo de ConcurrencyMode = " fijo "
Tengo dos preguntas:
-
Al no tener propiedades en mi modelo donde
ConcurrencyMode = " fixed "
, es seguro para mí asumir que si alguna vez se arroja unaOptimisticConcurrencyException
al guardar cambios, es porque la entidad ya no existe en el almacén de datos, es decir, ha sido eliminada por otro usuario, ¿o me falta algo?Imagino que EF ejecuta una declaración
UPDATE
que se parece a esto, que, según veo, solo provocará que se arroje unaOptimisticConcurrencyException
si la Persona con ID = 1 no existe:UPDATE Person SET FirstName = 'John' AND LastName = 'Smith' WHERE ID = 1
-
Cuando se utiliza
ConcurrencyMode = " fixed "
, ¿EF también comprueba la concurrencia al eliminar entidades? En otras palabras, EF ejecutará alguna vez una declaraciónDELETE
que tenga este aspecto (con más que solo la clave principal en la cláusulaWHERE
):DELETE FROM Person WHERE ID = 1 AND LastName = 'Doe'
Solución
Buena pregunta.
(1) Sí, pero desafortunadamente no es tan simple. Debido a que el EF (3.5) tiene un modelo de asociación independiente, la asociación también se trata de manera independiente, y aunque no lo haya dicho, se convierte en parte de las comprobaciones de concurrencia durante las ACTUALIZACIONES y SUPRIMACIONES.
es decir cuando actualiza a una Persona, a menudo verá actualizaciones que se ven así:
UPDATE Person SET Partner = NULL AND FirstName = 'John' AND LastName = 'Smith'
WHERE ID = 1 AND Partner = 2
es decir Partner es una columna FK.
Todo esto cambia en 4.0 si usa asociaciones FK, como esperamos que la mayoría de las personas también.
(2) Para ELIMINAR, cualquier propiedad ConcurrencyMode = 'fixed' SE MARCA durante la eliminación. La excepción es cuando tiene un SPROC para eliminar que no acepta los valores de concurrencia.
Espero que esto ayude
Alex