Reputation: 1073
I've a table "Orders" with columns: "Id", "ProductId", "Status", "Version".
"Version" is incremented with 1 after every changing of the row. This column is for control concurrency of several users changes.
For example, I read an order with Id=3 and Version=7. When I update it, I must be sure that nobody has changed this row yet. By SQL, I would write such script:
UPDATE Orders
SET Status = 'completed', Version = Version + 1
WHERE Id = 3 AND Version = 7
How can I write the same code by EF Core without using SQL command?
Upvotes: 1
Views: 2284
Reputation: 89424
Sure. Just mark Version
as a Concurrency Token and its pre-update value will be used in the WHERE
clause of any update. EG
modelBuilder.Entity<Order>()
.Property(o => o.Version)
.IsConcurrencyToken(true);
For a change like
var order = ...
order.Status = "Completed";
order.Version += 1;
db.SaveChanges();
The UPDATE will look something like this:
SET NOCOUNT ON;
UPDATE [Events] SET [Status] = @p0, [Version] = @p1
WHERE [Id] = @p2 AND [Version] = @p3;
SELECT @@ROWCOUNT;
And if the Version
has changed 0 rows will be affected and EF will throw an
DbUpdateConcurrencyException
indicating a concurrency conflict.
You can also use server-side incrementing for the concurrency token with additional configuration, or by using a provider-specific type like SQL Server's rowversion.
Upvotes: 2