When making changes to DbSet<> (like Add/Remove) what would be the order in which 'insert'/'delete' operations will be performed during SaveChanges?
Currently I'm observing 'deletes' before 'inserts' and that's what I would expect but couldn't find any official docs about it.
The problem I'm trying to prevent is that entities in question are controlled using unique constraint. And so I need to 'delete' old and 'insert' new ones. Doesn't matter in which order the 'inserts' would happen. What matters is the order of 'deletes' before 'inserts'.
Is this order described and fixed or we are forced to make SaveChanges in-between?
UPDATE_01:
Some more details.
Here is a sample minimized table schema:
CREATE TABLE "ClientContracts" (
"Id" int4 NOT NULL GENERATED ALWAYS AS IDENTITY,
"ClientId" int4 NOT NULL,
"Code" text NOT NULL,
"IsEnabled" bool NOT NULL,
CONSTRAINT "PK_ClientContracts" PRIMARY KEY ("Id")
);
CREATE UNIQUE INDEX "IX_ClientContracts_ClientId_IsEnabled" ON public."ClientContracts" USING btree ("ClientId", "IsEnabled") WHERE "IsEnabled";
CREATE UNIQUE INDEX "IX_ClientContracts_Code" ON public."ClientContracts" USING btree ("Code");
A client (ClientId) can have multiple contracts assigned to it. But only one of them is active in a given moment (IsEnabled) controlled with a IX_ClientContracts_ClientId_IsEnabled constraint. Also each contract's Code is unique and controlled with a IX_ClientContracts_Code constraint. There are cases when a contract could be deleted by a client and added again with the same Code. And sometimes it could an active one.
In order to fulfill both constraints I see 2 ways:
- first delete the needed contracts (the list of contracts is supplied by an external service),
SaveChanges, insert new ones andSaveChangesagain. This way we can be sure that constraints won't be 'triggered' since we have securely deleted previous entries before adding those that are in conflict. DbSet<ClientContracts>.Add/RemovethenSaveChangesand make EF handle deletes before inserts.
Multiple users and simultaneous changes are not accounted here. Single user at a time. Also an external service tries it's best to make sure that multiple contracts with the same code are not sent for processing (constraints are the 'last line of defense here').
So the main question is either we take the route (1) or (2).
Of course the most safest is (1) since we control the flow in this case. But this results in more code and more batches/connections.
So perhaps could it be safe to go for (2)?
And again. We are not talking about order of inserts or deletes themselves (i.e. doesn't matter if entity_1 is deleted after entity_3 or entity_5 is inserted before entity_1). Just about that deletes comes before inserts.