question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use INSERT w/OUTPUT Instead of INSERT+SELECT

See original GitHub issue

Entity Framework Core’s SQL Server provider (at least, as of v. 1.1.0) follows each INSERT statement with a SELECT statement that fetches database-generated values and verifies the inserted row count.

Proposal

Eliminate the SELECT statement. Instead:

  • Fetch database-generated values using an OUTPUT clause on the INSERT statement.
  • Rely on the database provider to throw an exception of the INSERT fails instead of verifying inserted row count (looks like was supposed to have been implemented per #2131).

Examples

Currently (EF Core 1.1.0)

-- Table w/identity column:
SET NOCOUNT ON;
INSERT INTO [TestTable1] ([Data])
VALUES (@p0);
SELECT [Id]
FROM [TestTable1]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();

-- Table w/identity and default value (`DEFAULT(GETDATE())`) columns:
SET NOCOUNT ON;
INSERT INTO [TestTable2] ([Data])
VALUES (@p0);
SELECT [Id], [HasDefaultValue]
FROM [TestTable2]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();

Proposed Simplification

-- Table w/identity column:
SET NOCOUNT ON;
INSERT INTO [TestTable1] ([Data])
    OUTPUT INSERTED.[Id]
VALUES (@p0);

-- Table w/identity and default value (`DEFAULT(GETDATE())`) columns:
SET NOCOUNT ON;
INSERT INTO [TestTable2] ([Data])
    OUTPUT INSERTED.[Id], INSERTED.[HasDefaultValue]
VALUES (@p0);

Example Code

Example.zip

Further technical details

EF Core version: 1.1.0 Operating system: Windows 10 Visual Studio version: VS 2015

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

6reactions
Coder3333commented, Aug 29, 2019

I am getting heavy deadlocking issues from the 2 step approach, and this is when I am only doing 2 simultaneous inserts into a table. If EF were using the output clause to get the identity, instead of a separate query, I do not think I would have the deadlock issues. Would it make sense to add an option for developers to choose how the insert is handled for folks that are not concerned about triggers?

Read more comments on GitHub >

github_iconTop Results From Across the Web

INSERT INTO with SELECT using OUTPUT
I want to store the pt_id into my temporary table by using OUTPUT , however I'm not inserting pt_id into ct_tarf , what...
Read more >
OUTPUT clause (Transact-SQL) - SQL Server
Returns information from, or expressions based on, each row affected by an INSERT, UPDATE, DELETE, or MERGE statement.
Read more >
Using source columns in OUTPUT INTO clause of an ...
I am writing a batch processing insert statement and would like to use a temp table to keep track of inserted ID's instead...
Read more >
How to Insert Rows and Get Their Identity Values with the ...
Instead, use the OUTPUT clause.​​ SELECT * FROM #RowsInserted; The OUTPUT clause is kinda like the virtual INSERTED/DELETED tables: it lets you ...
Read more >
The OUTPUT Clause for INSERT and DELETE Statements
Using the OUTPUT clause, we can display the rows inserted into a table in the output window by selecting the column names with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found