Given the following database design:
And using the example data below:
How would I delete the record with NodeId
= 3, and then update the line numbers on the remaining records to keep them sequential (in increments of 10)?
The code below highlights my attempt at doing this, but I am currently getting a unique Key Constraint Violation exception when I call SaveChanges()
.
private void Delete(string taskId, string nodeId)
{
using (var context = new CustomContext())
{
var taskStore = new TaskRepository(context);
var task = taskStore.GetById(taskId);
if ( task != null )
{
var deleteNode = task.Nodes.FirstOrDefault(n => n.NodeId == nodeId);
if ( deleteNode != null )
{
task.Nodes.Remove(deleteNode);
}
var lineCounter = 0;
foreach ( var node in task.Nodes )
{
node.LineNumber = lineCounter += 10;
}
}
context.SaveChanges();
}
}
I assume this has something to do with the sequence of the SQL statements or something not being updated correctly in the context cache. I would expect to see a unique key violation if the line numbers were updated before the conflicting row was updated, but I'm deleting the row first.
This is the process as I see it:
Step 1 (Context, Entities & DB are in sync)
Context Task.Nodes Database
1 / AAA / 10 (EntityState=Unchanged) 1 / AAA / 10 1 / AAA / 10
2 / AAA / 20 (EntityState=Unchanged) 2 / AAA / 20 2 / AAA / 20
3 / AAA / 30 (EntityState=Unchanged) 3 / AAA / 30 3 / AAA / 30
4 / AAA / 40 (EntityState=Unchanged) 4 / AAA / 40 4 / AAA / 40
5 / AAA / 50 (EntityState=Unchanged) 5 / AAA / 50 5 / AAA / 50
Step 2 (Node with NodeID == 3 removed)
Context Task.Nodes Database
1 / AAA / 10 (EntityState=Unchanged) 1 / AAA / 10 1 / AAA / 10
2 / AAA / 20 (EntityState=Unchanged) 2 / AAA / 20 2 / AAA / 20
3 / AAA / 30 (EntityState=Deleted=>Detached) **deleted** 3 / AAA / 30
4 / AAA / 40 (EntityState=Unchanged) 4 / AAA / 40 4 / AAA / 40
5 / AAA / 50 (EntityState=Unchanged) 5 / AAA / 50 5 / AAA / 50
Step 3 (Update line numbers for remaining nodes)
Context Task.Nodes Database
1 / AAA / 10 (EntityState=Unchanged) 1 / AAA / 10 1 / AAA / 10
2 / AAA / 20 (EntityState=Unchanged) 2 / AAA / 20 2 / AAA / 20
3 / AAA / 30 (EntityState=Deleted=>Detached) **deleted** 3 / AAA / 30
4 / AAA / 40 (EntityState=Modified) 4 / AAA / 30 4 / AAA / 40
5 / AAA / 50 (EntityState=Modified) 5 / AAA / 40 5 / AAA / 50
Step 4 (context.SaveChanges()
)
I imagine that this is the SQL in the order of execution. Since the unique constraint only exists in the database, this is where the violation will occur. However, given the sequence below, I do not understand why the violation is occurring as there are no duplicates.
//Begin Transaction
DELETE FROM NODES WHERE NODEID = 3;
UPDATE NODES SET LINENUMBER = 30 WHERE NODEID = 4;
UPDATE NODES SET LINENUMBER = 40 WHERE NODEID = 5;
//End Transaction
The answers to this question appear to agree with me that this is the expected sequence of SQL commands.
I have tried calling SaveChanges()
before updating the line numbers as well as after updating the line numbers but this gives the same error.
Calling SaveChanges()
within the loop works fine but the statements are not executed in a single transaction as I would like.
I seem to remember there being something in Entity Framework which allowed you to specify the order in which SQL Statements were executed but I don't remember the method name. Searching Google hasn't help so far, I'm still looking.
I may also need to insert records and update the line numbers as appropriate, any solution should bear this in mind.
Thanks, Phil