Entity Framework: recupera l’ID prima di “SaveChanges” all’interno di una transazione

In Entity Framework: esiste un modo per recuperare un ID (identity framework) appena creato all’interno di una transazione prima di chiamare “SaveChanges”?

Ho bisogno dell’ID per un secondo inserto, tuttavia viene sempre restituito come 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(); 

L’ID viene generato dal database dopo che la riga è stata inserita nella tabella. Non puoi chiedere al database quale sarà quel valore prima che la riga venga inserita.

Ci sono due modi per aggirare questo: il più semplice sarebbe chiamare SaveChanges . Dato che ci si trova all’interno di una transazione, è ansible eseguire il rollback in caso di problemi dopo aver ottenuto l’ID.

Il secondo modo sarebbe non utilizzare i campi IDENTITY incorporati nel database, ma piuttosto implementarli tu stesso. Questo può essere molto utile quando si hanno molte operazioni di inserimento di massa, ma viene fornito con un prezzo – non è banale da implementare.

EDIT: SQL Server 2012 ha un tipo SEQUENCE incorporato che può essere utilizzato al posto di una colonna IDENTITY, senza bisogno di implementarlo da solo.

@zmbq ha ragione, puoi solo ottenere l’id dopo aver chiamato save changes.

Il mio suggerimento è che NON si deve fare affidamento sull’ID generato del database. Il database dovrebbe solo un dettaglio della tua applicazione, non una parte integrante e non modificabile.

Se non è ansible aggirare il problema, utilizzare un GUID come identificatore a causa della sua unicità. MSSQL supporta GUID come tipo di colonna nativa ed è veloce (anche se non più veloce di INT.).

Saluti

Se la tua quadro tblTest è connessa ad altre quadro che vuoi albind, non è necessario che l’ID crei la relazione. Diciamo che tblTest è collegato a un altro object Test, così come in un altro object Test dell’object sono presenti le proprietà tblTest object e tblTestId, in tal caso è ansible avere questo codice:

 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; .... } } 

Dopo aver inviato la relazione verrebbe creato e non è necessario preoccuparsi di Id e così via.