鉴于以下数据库设计:
使用以下示例数据:
如何删除NodeId
= 3的记录,然后更新剩余记录中的行号以保持顺序(以10为增量)?
下面的代码突出显示了我这样做的尝试,但当我致电SaveChanges()
时,我目前正在获得一个独特的Key Constraint Violation异常。
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();
}
}
我认为这与SQL语句的序列或在上下文缓存中未正确更新的内容有关。 如果在更新冲突行之前更新了行号,我希望看到一个唯一的密钥违规,但我先删除该行。
这是我看到的过程:
第1步(上下文,实体和数据库同步)
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
第2步(删除了NodeID == 3的节点)
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
步骤3(更新剩余节点的行号)
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
第4步(context.SaveChanges()
)
我认为这是执行顺序中的SQL。 由于唯一约束仅存在于数据库中,因此这将发生违规。但是,鉴于以下顺序,我不明白为什么违规发生,因为没有重复。
//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
this question的答案似乎与我一致认为这是预期的SQL命令序列。
我在更新行号之前以及更新行号之后尝试调用SaveChanges()
,但这会产生相同的错误。
在循环中调用SaveChanges()
可以正常工作,但语句不会在我想要的单个事务中执行。
我似乎记得在Entity Framework中有一些东西允许你指定执行SQL语句的顺序但我不记得方法名称。到目前为止,搜索Google并没有帮助,我仍在寻找。
我可能还需要插入记录并根据需要更新行号,任何解决方案都应牢记这一点。
谢谢, 菲尔