2014-12-28 20 views
6

Quando si sta salvando un'entità utilizzando EF 6.1, il seguente codice SQL viene generato ed eseguito:Perché Entity Framework 6 non seleziona solo scope_identity() dopo l'inserimento?

exec sp_executesql N'INSERT [dbo].[Customers]([Name], [FirstName]) 
VALUES (@0, @1) 
SELECT [CustomerId] 
FROM [dbo].[Customers] 
WHERE @@ROWCOUNT > 0 AND [CustomerId] = scope_identity()',N'@0 nvarchar(max) ,@1 nvarchar(max) ',@0=N'Wenk',@1=N'Manuel' 

ho capito, che l'inserto/SELECT è fatto, per recuperare il valore del immediatley colonna CustomerID dopo Salvataggio. Per quanto ne so, SCOPE_IDENTITY() restituisce il valore, quindi perché non ci sia qualcosa di simile

SELECT scope_identity() 

invece di tutta quella roba che richiedono letture fisiche?

Cheers, Manuel

+0

Non una risposta alla tua domanda, ma si consiglia di utilizzare i tipi di dati più appropriato di 'nvarchar (max)' per le colonne come "nome" e "FirstName" –

+1

Forse è quello di ottenere un risultato con il corretto tipo di dati della colonna . –

risposta

1

corretta. scope_identity() è lì per ottenere il valore generato CustomerId, quindi EF può usarlo come chiave di entità. Penso, ma devo indovinare perché non è documentato, lo tabella è fatto sulla tabella Customer per assicurarsi che il recuperato scope_identity() sia realmente correlato a CustomerId. Ci possono essere casi in cui un INSERT attiva più inserti in modo che scope_identity() sia assegnato a un altro record.

Un secondo motivo per interrogare la tabella Customer è che questa query viene generata in un metodo che può anche aggiungere colonne calcolate alla clausola SELECT. Probabilmente era più comodo interrogare la tabella delle entità comunque.

La clausola WHERE @@ROWCOUNT > 0 viene aggiunta per garantire che il numero previsto di righe sia interessato dall'istruzione INSERT. Nel codice sorgente di EF c'è un commento:

Si noti che filtriamo sul conteggio delle righe per garantire che non vengano restituite righe se non sono state modificate righe.

+2

Per quanto riguarda la tua teoria "inserisci trigger più inserti", scope_identity' non otterrà mai l'identità vale da un inserto in un altro ambito come un trigger. Questo è il motivo per preferirlo a '@@ identity' –

+0

@MartinSmith No, non in un altro ambito. Ma forse ci sono degli scenari in cui gli inserimenti avvengono nello stesso ambito. Penso che siano solo cauti. Ma ottenere il tipo di dati corretto (come dici sopra) mi sembra anche una buona ragione. –

+0

@ gert-arnold: la tua seconda ipotesi non può essere la ragione perché solo la colonna id viene selezionata dopo l'inserimento in modo da non ottenere i valori delle colonne calcolate. Se il primo motivo è corretto, anziché un trigger che fa 3 inserimenti nella tabella dei clienti anziché uno potrebbe portare a un errore scope_identity(). Il valore recuperato non potrebbe essere sbagliato di? –

Problemi correlati