Open jaliyaudagedara opened 3 years ago
The previous/wrong product2 is still in the context because the DBTransaction will roll back the database, but not the DBContext. So you are trying to insert the wrong product again. By design, the cache of the context will not be changed when you roll back a transaction.
You forgot to remove the previous/wrong product2 from the context before saving again: // Remove the wrong product first context.Remove(context.Products.Local.FirstOrDefault(x=>x.Name=="Some Product 2"));
In your case you could also just correct the CategoryId: // correct the Category on the existing object context.Products.Local.FirstOrDefault(x => x.Name == "Some Product 2").CategoryId = category.Id;
Either keep a reference to the previous/wrong product2 or look for it in the local cache.
Corrected Code:
...
catch (Exception)
{
await transaction.RollbackToSavepointAsync("Product1Created");
// correct the CategoryId on the existing object
context.Products.Local.FirstOrDefault(x => x.Name == "Some Product 2").CategoryId = category.Id;
// OR: Remove the wrong product first
//context.Remove(context.Products.Local.FirstOrDefault(x=>x.Name=="Some Product 2"));
// Setting the correct CategoryId FK
var product2 = new Product { Name = "Some Product 2 with Correct Category Id", CategoryId = category.Id };
context.Products.Add(product2);
await context.SaveChangesAsync();
await transaction.CommitAsync();
}
Holger Schwichtenberg www.EFCore.net
Thanks @HSchwichtenberg!
I see, that makes sense now. I was under the impression when we do the Rollback to a given SavePoint, the context also getting rollbacked.
Guess, this is what confused me (https://docs.microsoft.com/en-us/ef/core/saving/transactions#savepoints).
Maybe we might need to update the documentation?
Thanks again for the nice explanation.
EF Core version: 5.0.5 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 5 Operating system: Windows 10 IDE: Microsoft Visual Studio Enterprise 2019 Preview, Version 16.10.0 Preview 2.1
Consider the below database context.
Now I am trying this.
In the catch here, I am rolling back to the SavePoint
Product1Created
and restarting adding theproduct2
with Correct FK for CategoryId (Note: different product name as well).And inside the catch, again this is getting thrown,
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Products_Categories_CategoryId". The conflict occurred in database "EfCore5", table "dbo.Categories", column 'Id'.
Full stacktrace,
When I check the log, found an interesting thing. On the catch, when I am inserting the correct
product2
it's still using the previousproduct2
values. (I changed theproduct2
name on the insert inside catch to a different one to make it clear)