-
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
Inserted entities has different ID (DB vs instance) after SaveChanges #4080
Comments
@LonDat thanks for the bug report. I would like to confirm my interpretation of the bug report is correct. Do you mean that after we read the generated values in
the objects in the context are:
Or is the issue that you expected the IDs of the entities to be in the same order in which you added them to the context and that isn't happening? BTW, the two main reasons I ask are:
|
If we are actually getting the wrong identities assigned to entities this is a possible cause: From Ordering guarantees in SQL Server...:
This might mean that the order or the rows in the INSERTED table is not what we expect. |
Hi, thx for quick reply. I tried this: var x = new object[reader.FieldCount];
var xx = reader.GetValues(x);
System.IO.File.AppendAllLines(@"C:\temp\idx.log", new[] {$"{commandIndex:0000}: {x[0]}"}); And I get this:
This is SQL DDL: CREATE TABLE [dbo].[EmailMessageAddress](
[Id] [int] IDENTITY(1,1) NOT NULL,
[AddressId] [int] NULL,
[AddressType] [int] NOT NULL,
[DisplayName] [nvarchar](150) NULL,
[MessageId] [int] NOT NULL,
CONSTRAINT [PK_EmailMessageAddress] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[EmailMessageAddress] WITH CHECK ADD CONSTRAINT [FK_EmailMessageAddress_EmailAddress_AddressId] FOREIGN KEY([AddressId])
REFERENCES [dbo].[EmailAddress] ([Id])
GO
ALTER TABLE [dbo].[EmailMessageAddress] CHECK CONSTRAINT [FK_EmailMessageAddress_EmailAddress_AddressId]
GO
ALTER TABLE [dbo].[EmailMessageAddress] WITH CHECK ADD CONSTRAINT [FK_EmailMessageAddress_EmailMessage_MessageId] FOREIGN KEY([MessageId])
REFERENCES [dbo].[EmailMessage] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[EmailMessageAddress] CHECK CONSTRAINT [FK_EmailMessageAddress_EmailMessage_MessageId]
GO It's true, that I try run generated command (from SQL profiler) run directly in SQL management (with directly typed values), I never get ID's in wrong order :( Thx, |
@LonDat Makes sense. Thanks a lot for the report! @rowanmiller & others in triage, @AndriySvyryd and I discussed this and we believe it is a very high priority to fix. |
Agreed. |
Some data from my environment...perhaps this helps. batch.sql.txt Everything is from one test...idx-order.txt is from my test in ConsumeResultSetWithPropagation described in my last post. Thx again... |
To reproduce, you'll also need to add the following DDL: CREATE TABLE [dbo].[EmailMessage](
[Id] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_EmailMessage] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[EmailAddress](
[Id] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_EmailAddress] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] Filling them with data will make the batch.sql.txt linked by @LonDat 's insert succeed and produce the same query plan as linked. DECLARE @count int;
SET @count = 0;
WHILE @count < 100000
BEGIN
INSERT INTO EmailAddress DEFAULT VALUES;
INSERT INTO EmailMessage DEFAULT VALUES;
SET @count = @count + 1;
END I first tried adding an identity column to the variable table with negative results -- the order of the variable table's identity ids was the order that the values were being outputted originally. Based on my understanding of the query plan and testing, it appears the only valid solution is to add "ORDER BY [Id]" to "SELECT [Id] FROM @generated524" when the column is expected to be an identity column. The guarantee talked about in the MSDN blog linked by @divega does apparently mean that the order of the items being inserted into the primary table is guaranteed, but the order of the items that are outputted to the table variable are based on undefined factors (in this case, FK constraint verification causes sorting 2x prior to being inserted into to the variable's table, as seen in the plan linked by @LonDat ). |
I came up with a way to sort the results, but it might not be the most efficient query: http://stackoverflow.com/questions/34362390/return-inserted-rows-in-inserted-order-in-sql-server/34362391 |
…nserts for Sql Server. Fixes #4080
Hi guys...
I have problem with inserting more entities (same class).
My environment: MSSQL 2014 (this trouble may appears on MSSQL 2012+).
Situation:
Create 500 instances of one type entity a call SaveChanges.
You generate one insert with many values and identity insert into temporary table...but:
"There is no guarantee that the order in which the changes are applied to the table and the order in which the rows are inserted into the output table or table variable will correspond." (source: https://msdn.microsoft.com/en-us/library/ms177564.aspx or http://stackoverflow.com/questions/11222043/table-valued-function-order-by-is-ignored-in-output).
I have table with identity (no big deal...default identity(1, 1)) and DbReader output is:
This is fatal when you need continue work with instances :(
Thx for fix,
Milan
The text was updated successfully, but these errors were encountered: