Saltar al contenido

Entity Framework: recupere la ID antes de ‘Guardar cambios’ dentro de una transacción

Te doy la bienvenida a proyecto on line, ahora encontrarás la respuesta que estabas buscando.

Solución:

La base de datos genera el ID después de insertar la fila en la tabla. No puede preguntarle a la base de datos cuál será ese valor antes de que se inserte la fila.

Tiene dos formas de evitar esto: la más fácil sería llamar SaveChanges. Como se encuentra dentro de una transacción, puede retroceder en caso de que haya un problema después de obtener la identificación.

La segunda forma sería no utilizar la base de datos integrada IDENTITY campos, sino implementarlos usted mismo. Esto puede ser muy útil cuando tiene muchas operaciones de inserción masiva, pero tiene un precio: no es trivial de implementar.

EDITAR: SQL Server 2012 tiene un tipo SEQUENCE incorporado que se puede usar en lugar de una columna IDENTITY, no es necesario que lo implemente usted mismo.

Como ya han señalado otros, no tiene acceso al valor de incremento generado por la base de datos antes saveChanges() fue llamado; sin embargo, si solo está interesado en el id como un medio para establecer una conexión con otra entidad (por ejemplo, en la misma transacción), también puede confiar en los identificadores temporales asignados por EF Core:

Según el proveedor de la base de datos que se utilice, EF puede generar valores del lado del cliente o en la base de datos. Si el valor es generado por la base de datos, entonces EF puede asignar un valor temporal cuando agrega la entidad al contexto. Este valor temporal será reemplazado por el valor generado por la base de datos durante SaveChanges().

Aquí hay un ejemplo para demostrar cómo funciona esto. Decir MyEntity es referenciado por MyOtherEntity a través de la propiedad MyEntityId que debe ser asignado antes saveChanges se llama.

var x = new MyEntity();        // x.Id = 0
dbContext.Add(x);              // x.Id = -2147482624 <-- EF Core generated id
var y = new MyOtherEntity();   // y.Id = 0
dbContext.Add(y);              // y.Id = -2147482623 <-- EF Core generated id
y.MyEntityId = x.Id;           // y.MyEntityId = -2147482624
dbContext.SaveChangesAsync();
Debug.WriteLine(x.Id);         // 1261 <- EF Core replaced temp id with "real" id
Debug.WriteLine(y.MyEntityId); // 1261 <- reference also adjusted by EF Core

Lo anterior también funciona cuando se asignan referencias a través de propiedades de navegación, es decir y.MyEntity = x en lugar de y.MyEntityId = x.Id

@zmbq tiene razón, solo puede obtener la identificación después de llamar a guardar cambios.

Mi sugerencia es que NO debe confiar en las ID generadas de la base de datos. La base de datos debe ser solo un detalle de su aplicación, no una parte integral e inmutable.

Si no puede solucionar ese problema, use un GUID como identificador debido a su singularidad. MSSQL admite GUID como un tipo de columna nativo y es rápido (aunque no más rápido que INT).

Salud

Si estás de acuerdo, tienes el poder dejar un escrito acerca de qué te ha gustado de esta sección.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *