2017-02-24 109 views
2

我只是想改變「訂單」價值兩個要素,我有以下代碼:實體框架 - 重新排序元素

 int tmpItemOrder = item1.Order; 
     item1.Order = item2.Order; 
     item2.Order = tmpItemOrder; 

     await _db.SaveChangesAsync(); 

,但我得到的唯一關鍵的問題(順序是唯一鍵)

{「的唯一鍵約束‘IX_EscortItems’。衝突不能插入對象‘dbo.EscortItems’ 重複鍵。重複的關鍵值是 (2,20)。\ r \ n該語句已終止。」}

據我所知,當系統嘗試設置一個dublicate密鑰時,即使在事務中也會引發錯誤。奇怪的行爲,但現狀。

如何正確解決此問題?

+3

有人猜測,如果按順序更新值,只要第一個值被設置,它將立即違反唯一鍵約束。即使兩個'SaveChanges'調用也會有相同的效果。您可能必須使用中間唯一值。 –

+2

另一種觀點認爲,交換密鑰並不常見,也許問題需要一種不同的方法 - 只是一個想法。 –

+0

@PeterSmith,你是對的,即使兩個SaveChanges調用也有同樣的效果! –

回答

2

不僅在交易完成時,必須遵守唯一約束條件,即每行更新。試圖對行重新排序需要仔細的算法。爲了更新一行以獲得所需的'訂單'X,您必須首先確保X是空閒的(即,沒有行已經有了這個訂單)。如果一行已經有了這個期望的訂單,你必須通過將其更新爲'空閒'值來將其移出該'空格'(我留下作爲練習找到這樣一個'空閒'值)。在更新'訂單'之前,將其應用於每一行。

這將是更容易刪除所有行,然後將它們插回到所需的'順序'。

這就是說,有很多爲什麼你不想在一列中堅持'訂單'的原因。只要提一個,就會必須處理差距。

+0

那麼如何解決這個問題呢?單鏈表? –

+0

鏈接列表(即爲每行保留一個「下一個項目ID」列)很容易更新,但很難按順序查詢*(除非您願意在應用程序中對客戶端項目進行排序,可行的小套,如發票或'購物車') –

+0

並有更新相同的問題... –