When you're saving an entity using EF 6.1, the following SQL Code is generated and executed:
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'
I understand, that the insert/select is done, to retrieve the value of the CustomerId Column immediatley after saving. As far as I know, scope_identity() returns the value, so why isn’t there something like
SELECT scope_identity()
instead of all that stuff that require physical reads?
Cheers, Manuel
Correct.
scope_identity()
is there to get the generatedCustomerId
value, so EF can use it as entity key. I think, but I have to guess because it's not documented, theSELECT
is done on theCustomer
table to make sure the retrievedscope_identity()
really is related toCustomerId
. There may be cases that anINSERT
triggers more inserts soscope_identity()
is allotted to another record.A second reason to query the
Customer
table is that this query is generated in one method that may also add computed columns to the SELECT clause. It was probably more convenient to query the entity table anyway.The
WHERE @@ROWCOUNT > 0
clause is added to make sure that the expected number of rows is affected by theINSERT
statement. In EF's source code there is a comment: