我有一个名为“LineItem”的表,其中包含“SortOrder 和 Bom_Fk”列,并且这些列上有唯一键约束。
假设表格有如下两行
ID | SortOrder| Bom_Fk
1 | 1 | 122
2 | 2 | 122
现在,我更新这些行如下
ID | SortORder| Bom_Fk
1 | 2 | 122
2 | 1 | 122
我只是在颠倒订单项的排序顺序。
注意SortOrder不为空,唯一约束
尝试从 EF 核心更新时,这会在更新第一个行项目时引发唯一约束错误,因为第二个行项目在数据库中的排序顺序为 2。 所以我想使用 UpdateRange(..) 进行批量更新,但这会引发如下所述的错误。
<块引用>无法保存更改,因为在 要保存的数据:'LineItem [Modified] <-\r\nIndex { 'BomFk', 'SortOrder' } LineItem [修改] <-\r\nIndex { 'BomFk', 'SortOrder' } LineItem [修改]显示附加信息调用 'DbContextOptionsBuilder.EnableSensitiveDataLogging'。'。"
用于更新到此表的代码...
lineItemsToUpdate.Add(lineItem);
context.LineItems.UpdateRange(lineItemsToUpdate);
我打算将 SortOrder 设为 null 并确保它不是来自代码的 null... 这样我就可以用 null 更新所有 LineItems,然后用新值更新。(我还没有尝试过,为唯一约束设置 null 不是一个好主意,但这是我计划尝试的工作)
有什么办法可以让它保持“排序顺序为非空唯一列”?
答案 0 :(得分:1)
我认为 sortorder 值是 1、2、3 还是 101、102、103 并不重要。我通常使用数百或数千来表示。在这种情况下,将项目从一个地方移动到另一个地方会更容易。
所以你可以试试这个
var maxSortOrder= context.LineItems.Max(i=>i.SortOrder);
foreach(var item in lineItemsToUpdate)
{
maxSortOrder+=1;
item.SortOrder=maxSortOrder;
}
此后您可以保存范围。
如果 sortOrder 值很重要,保存后您可以使用任何数字再次排序。
另一种方法是使用原始 sql 查询来关闭和打开唯一约束。但这是非常不安全的,如果您的数据有错误,您将遇到大问题。此功能通常用于将数据从一个数据库或表迁移到另一个数据库或表。