2012-06-29 11 views
5

Dado que EF no admite exclusiones de claves únicas, parece que debemos detectar excepciones durante el método Save y mostrar un mensaje de error al usuario.EF CodeFirst manejo de las excepciones de la base de datos al guardar los cambios

Los problemas con este enfoque son:

  • ¿cómo sabemos que registran inició una excepción
  • ¿cómo sabemos qué tipo de problema inició una excepción (por ejemplo, podría tener dos restricciones únicas en igual registro, así que tengo que decirle al usuario que se está roto)

DBMS es SqlServer 2008.

Cómo resolver estos problemas?

Respuesta

2

Si permite que un usuario puede introducir valores que deben ser únicos en la base de datos debe validar esta entrada antes de guardar los cambios:

if (context.Customers.Any(c => c.SomeUniqueProperty == userInput)) 
    // return to user with a message to change the input value 
else 
    context.SaveChanges(); 

Esto no es sólo el caso de valores con restricciones únicas en la base de datos pero también para ingresar valores de clave foránea que deben referirse a registros de destino existentes o valores de clave primaria si la clave primaria no se genera automáticamente en la base de datos. EF no lo ayuda en la última situación, ya sea porque un contexto no conoce el contenido de la tabla de la base de datos completa, sino solo las entidades que están actualmente asociadas al contexto. Es cierto que EF prohibirá adjuntar dos objetos con la misma clave principal pero permite dos objetos con la misma restricción de clave única. Pero esto no lo protege completamente contra violaciones de restricciones de clave primaria cuando guarda cambios en la base de datos.

En el caso poco probable de que entre el Any cheque y SaveChanges otro usuario ha introducido un registro con el mismo valor, consideraría la excepción occuring como no es posible manejar y simplemente decirle al usuario "se produjo un error esperado, intenta de nuevo...". Si el usuario vuelve a intentar, la comprobación Any se repite y obtendrá el mensaje más útil para cambiar el valor de entrada del código anterior.

La excepción devuelta para tales restricciones de restricción de clave primaria o clave primaria es un DbUpdateException general y una de las excepciones internas será un SqlException que contiene como una de sus propiedades un código de error de SQL Server. Cualquier otro detalle se puede encontrar solo en el mensaje de excepción "Infracción de la restricción UNIQUE KEY IX_SomeUniqueProperty_Index ..." o similar. Si espera que el usuario pueda comprender y reaccionar de acuerdo con esta información, podría mostrarla. De lo contrario, podría registrar este mensaje para que un administrador o desarrollador verifique posibles errores u otros problemas.

+0

Por lo tanto, dado que estoy haciendo actualizaciones por lotes, esto requeriría buscar registros actualizados/agregados en Clientes, y recorrer cada registro para verificar si hay un registro existente con el mismo valor. No estoy seguro de cómo afectará el rendimiento cuando hay más de 10 registros modificados. ¿O en este caso es mejor simplemente atrapar una excepción? El mensaje debe estar localizado, así que parece que necesito crear un procedimiento que haga una búsqueda de mensajes para IX_SomeUniqueProperty, ya que el mensaje también puede estar en francés, si OS es francés (si no me equivoco), y no puedo depender en "Violación de ...." – Goran

+0

@Goran: Ya veo, pero aún haría una consulta para verificar la existencia. Si también necesita * actualizar * como dice, no solo insertar, ¿no necesita consultar la entidad en la base de datos de todos modos? No puede decidir entre actualizar e insertar sin saber si la entidad ya está en la base de datos o no. – Slauma

+0

EF toma la decisión de actualizar e insertar.Cualquier entidad que haya agregado a la colección Clientes se considera como un nuevo registro, los registros con PK ya asignado se actualizarán. Lo que necesito cubrir es el caso en que un usuario de la red agregó un registro (los datos del cliente no están en la mayoría de los casos actualizados con los datos de la base de datos, ya que eso requeriría resincronización constante), por lo que podría haber 15 minutos entre el último Carga de datos y guardar cambios. Por este motivo, no solo puedo depender de los datos que se almacenan en la memoria caché del cliente para verificar si existen restricciones únicas (o cualquier otra). – Goran

Cuestiones relacionadas