-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EF Core database insert fails when table has a SQL INSTEAD OF trigger #12064
Comments
Duplicate of #10443 |
Oops. I believe I did see that case earlier but was unsure if it was a duplicate because I'm not deleting any rows, however I have just noticed the latest posts there also reference upserts. Is there any workaround for this? |
@AndriySvyryd to look into workarounds |
I have figured out a workaround. Following reading this, and observing that they As a result, my workaround is, in my CREATE TRIGGER trTestTable_ioiu ON TestTable INSTEAD OF INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
IF EXISTS(SELECT * FROM [inserted]) AND NOT EXISTS(SELECT * FROM [deleted]) --Insert
BEGIN
DECLARE @t TABLE([Id] INTEGER NOT NULL)
INSERT INTO [TestTable]([Value], [DateUpdated]) OUTPUT [inserted].[Id] INTO @t
SELECT [i].[Value], DATEDIFF(SECOND, CONVERT(DATETIME, '1970-01-01', 120), GETDATE())
FROM [inserted] AS [i]
SELECT * FROM @t
END
ELSE IF EXISTS(SELECT * FROM [inserted]) AND EXISTS(SELECT * FROM [deleted]) --Update
BEGIN
UPDATE [tt]
SET [tt].[Value] = [i].[Value],
[tt].[DateUpdated] = DATEDIFF(SECOND, CONVERT(DATETIME, '1970-01-01', 120), GETDATE())
FROM [TestTable] AS [tt]
INNER JOIN [inserted] AS [i] ON [i].[Id] = [tt].[Id]
WHERE [tt].[Value] <> [i].[Value]
END
END |
@Metritutus This workaround will only work for so long, because the ability for a trigger to return a result set is deprecated (https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017#returning-results). Also, it may be better to run the select statement as
since that is what Entity Framework is actually running when it generates the batch statement for inserts. |
@saluce65 Darn, I was unaware of the impending deprecation of that piece of trigger functionality. With regards to |
@Metritutus
with
since all EF cares about it getting back the last identity value inserted. |
@saluce65 I stand corrected! When I was thinking back to this I thought that was the reason I didn't use I suspect the actual reason may simply have been because it was my understanding that Entity Framework Core does more than just get the Id of the newly-inserted record. I was under the impression that Entity Framework Core uses an However this is all ultimately superfluous as it doesn't address the greater issue of how to get the above-mentioned values back to Entity Framework Core when utilising an EDIT: One approach that does come to mind though is removing the |
I've tested the suggested solution by @saluce65
with EF version 5.04 and it works! PD: In my case the trigger also update another two int columns. |
Related: #25406 |
EF Triage: Currently this is by-design and triggers need to account for what EF is expecting, #10443 tracks adding an opt-out. |
I have a table in SQL Server that utilises an
INSTEAD OF
trigger to update a column with a unix timestamp representing when the record was updated.When attempting to insert a record into this table from Entity Framework Core, a
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException
is thrown.The SQL scripts, non-generated application code and the scaffold command used are below.
SQL scripts
Application code
Stacktrace
Scaffold command:
Scaffold-DbContext "Server=DbServer;Database=EFCoreTriggerTest;User ID=<REMOVED>;Password=<REMOVED>;" Microsoft.EntityFrameworkCore.SqlServer -Force -OutputDir Models
Why am I getting this error? Are there other steps I need to take in order to allow this operation to succeed?
Further technical details
EF Core version: netcoreapp2.1
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2017 15.7.1
The text was updated successfully, but these errors were encountered: