Entity Framework: recupera el ID antes de ‘SaveChanges’ dentro de una transacción

En Entity Framework: ¿hay alguna forma de recuperar una ID (identidad) recién creada dentro de una transacción antes de llamar a ‘SaveChanges’?

Necesito el ID para un segundo inserto, sin embargo, siempre se devuelve como 0 …

ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; objectContext.Connection.Open(); using (var transaction = objectContext.Connection.BeginTransaction()) { foreach (tblTest entity in saveItems) { this.context.Entry(entity).State = System.Data.EntityState.Added; this.context.Set().Add(entity); int testId = entity.TestID; .... Add another item using testId } try { context.SaveChanges(); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); objectContext.Connection.Close(); throw ex; } } objectContext.Connection.Close(); 

La ID genera la ID una vez que la fila se inserta en la tabla. No puede preguntar a la base de datos cuál será el valor antes de insertar la fila.

Hay dos formas de evitar esto: lo más fácil sería llamar a SaveChanges . Dado que está 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 los campos de IDENTITY incorporados en la base de datos, 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 incorporado un tipo de SECUENCIA que se puede usar en lugar de una columna de IDENTIDAD, no es necesario implementarlo usted mismo.

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

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

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

Aclamaciones

Si su entidad tblTest está conectada a otras entidades que desea adjuntar, no necesita tener el Id para crear la relación. Digamos que tblTest está adjuntado a otro objeto Test, de la misma manera que en otro objeto Test tiene propiedades tblTest object y tblTestId, en ese caso puede tener este código:

 using (var transaction = objectContext.Connection.BeginTransaction()) { foreach (tblTest entity in saveItems) { this.context.Entry(entity).State = System.Data.EntityState.Added; this.context.Set().Add(entity); anotherTest.tblTest = entity; .... } } 

Después de enviar la relación se creará y no necesita preocuparse por los Id, etc.