2011-01-21 34 views
5

¿Hay alguna manera de forzar el valor de ID para una nueva entidad en EF cuando tenemos una columna de autoaumento de ID, es decir, usar el comportamiento SET IDENTITY_INSERT a través de EF?Entity Framework SET IDENTITY_INSERT

Nuestro requisito es que nuestro formulario de creación siempre debe mostrar una ID nueva y única para el objeto que estamos creando en el formulario vacío antes de que se complete o se guarde. La idea es que este ID pueda leerse por teléfono y luego el usuario puede completar y guardar el formulario después de que se complete la llamada. Podríamos reservar una identificación insertando una fila vacía en la base de datos en ese momento, pero tenemos columnas únicas y FK; en su lugar, he creado una tabla de "próxima ID" que incrementamos con bloqueos por seguridad, y también la pruebo con la ID superior en la tabla de objetos para tener cuidado. La idea era forzar el uso de esta nueva identificación cuando redactamos la entidad, pero no veo cómo lograr que EF lo haga.

¿Es eso posible? ¿Es solo algo que me he perdido? No creo que la ID llegue incluso a la inserción, así que no creo que llamar manualmente a SET IDENTITY_INSERT alrededor de SaveChanges ayude.

¿O tengo que hacer otra cosa? Puedo ver alternativas:

  • Cambie nuestra columna de ID para que no sea una identidad y tome el control manual de todo: aquí hay una herencia de ID de tabla, así que esto es potencialmente complicado también.
  • Separar ID de DB e ID visible por el usuario en una columna separada, y registrar allí nuestra ID única.
  • Vaciar la fila para reservar la ID, como se indica arriba; podría necesitar algunos cambios de nulabilidad y modificar nuestro código de lectura de datos para ignorar estos registros.

Gracias! Esto es EF4 (utilizando un EDMX y clases generadas, no POCO), y en contra de SQL Server 2008 en caso de que importe.

+1

La única manera de garantizar la identificación es insertarla: jugar con 'SET IDENTITY INSERT' no solucionará el hecho de que tratará con posibles duplicados antes de alternar la funcionalidad para hacer frente a las limitaciones.¿Es esto realmente solo un problema con la necesidad de números secuenciales? –

+0

@OMG Ponies Sí, tal vez ese sea el camino a seguir después de todo. Sin embargo, las identificaciones duplicadas para insertar definitivamente serán el caso de excepción: los nuevos identificadores secuenciales que estamos alimentando se generaron en una tabla diferente con bloqueos, etc. por lo que, a menos que las cosas vayan inesperadamente mal, serán únicos. – Rup

+0

Si determina usted mismo los nuevos valores, ¿para qué necesita la especificación 'IDENTITY', en ese caso ??? –

Respuesta

1

¿Por qué no utilizar un Guid como clave principal. No tiene nada que ver con el incremento automático, sin dificultades de concurrencia, etc. Simplemente crea el Guid en el momento de crear el formulario. Entréguesela a la persona que llama y complete el formulario después. Cuando se cancela el formulario, no hay problema. Cuando el formulario se terminó crear la entidad con el Guid creado fijar los otros valores del objeto de entidad, que se aplican a la (a) contexto y SaveChanges (...)

+0

Gracias. Sin embargo, la identificación debe leerse a un ser humano, de modo que cuanto más simple, mejor. No veo la ventaja de utilizar esto en un número incrementado separado (que es un problema que ya he resuelto de todos modos) en una nueva columna: todavía tendremos que modificar todo nuestro código de búsqueda + búsqueda para buscar los nuevos valores en cambio, etc. Si se refería a la clave primaria de la tabla, entonces hay FKR en esta tabla (más la herencia de ID que mencioné), así que preferiría mantenerlo como un número entero. De nuevo, aparte de la aleatoriedad, no veo una ventaja aquí. – Rup

+0

Solo asegúrese de que ** NO ** deje que se convierta en la ** clave de agrupamiento ** en su tabla, sería terriblemente ineficiente y muy, muy malo para su base de datos .. –

+0

Ahora veo el problema más claramente ... cuando ID es creado por EF y está en la clave primaria, no es posible cambiarlo después, supongo ... Tal vez cuando separe la entidad del contexto ... Trabajo con Entidades de seguimiento personal ... una solución podría ser Detener el seguimiento de la entidad para cambiar un valor que está en la clave principal. ¡Tough one though! –

0

Las alternativas que suele alterar su esquema

  1. Use EF Transacción

Usted puede llamar context.SaveChanges() y obtener la clave principal autoincremented. Una vez que se completa el proceso, puede confirmar la transacción. Si la transacción se cancela o hay un error/excepción, siempre puede deshacerse para que no tenga agujeros/datos sucios en sus filas. Sugiero que use el patrón singleton y pase la misma transacción/contexto a los métodos o pantallas para completar el proceso.

  1. simplemente añada una situación adicional: Proyecto de

Guardar forma vacía como borrador con salvado de identificación, a continuación, proceder a editar el formulario con la información. Una vez completado, guarde el formulario como final/listo. Si no procede a guardar el formulario, siempre puede reciclar el borrador.