2016-08-22 71 views
1

我有一個屏幕上的產品圖像列表。當用戶拖放圖像到度假村時,我可以訪問oldIndex和newIndex。更新聲明,以便跟蹤數據庫中的SortOrder

可以說我有以下內容:
產品1 [指數:0]
產品2 [指數:1]
產品3 [指數:2]
產品4 [指數:3]
產品5 [指數:4]
產品6 [指數:5]

讓用戶決定把產品2產品4

我試着g來弄清楚我的數據庫更新語句是什麼。我正在閱讀另一篇文章,看到有人說你應該更新所有> = newIndex的產品的SortOrder字段,然後將新產品更新爲newIndex。

這個東西似乎離我的,這將讓我有以下幾點:
產品1 [指數:0]
產品2 [指數:2]
產品3 [指數:3]
產品4 [指數: 4]
產品5 [指數:5]
產品6 [指數:6]

我真的想實現這個在我的索引保持在完美的順序沒有間隙。有什麼建議麼?

+0

我以前用Entity Framework做過這種事情。它需要在SQL中嗎? –

+0

@BlakeRivell,請指定你使用哪個SQL服務器? – AlexK

+0

@dans是的我使用的是實體框架我只是假設某人用SQL來描述我最簡單。我正在使用kendo UI排序小部件,它允許我在列表視圖中拖放圖像,並且onChange可以訪問移動項目的oldIndex和newIndex。我的計劃是在此時進行ajax調用,以更新所有記錄排序順序。 –

回答

1

所以我寫了一個void來處理咕嚕聲。由於我需要使用多種類型的實體進行此操作,所有這些實體都有一個SortOrder列,因此我創建了一個名爲ISortable的界面,其中包含一個SortOrder列。如果你只是用一個數據庫表來做這件事,你可以用ISortable的任何實例替換任何實體命名的實例。

什麼需要這樣的空隙之外發生的情況是:

從數據庫中獲取您的項目,它的老排序順序存儲在一個變量(oldSortOrder),然後設置你的項目的新的排序順序(newSortOrder)然後將變量設置爲不是您剛更新的其他項目(list)。這也解釋了從數據庫中刪除的項目,只需在您的ajax調用中設置newSortOrder0即可。

的WebAPI方法:

// Code is activated when accessed via http PUT 
public void PutItem(int itemId, int newSortOrder) 
{ 
    // using makes sure Context is disposed of properly 
    using (var Context = new MyDbContext()) 
    { 
     var oldSortOrder = 0; 

     IEnumerable<ISortable> itemsToReorder = null; 

     // Get moved item from database 
     var item = Context.Items.FirstOrDefault(x => x.ItemId == itemId); 

     // Before we set the new sort order, set a variable to the 
     // old one. This will be used to reorder the other items. 
     oldSortOrder = item.SortOrder; 

     // Get all items except the one we grabbed above. 
     itemsToReorder = Context.Items.Where(x => x.ItemId != itemId); 

     // Delete if the item is set for deletion (newSortOrder = 0) 
     if (newSortOrder == 0) 
     { 
      Context.Items.Remove(item); 
     } 
     // Otherwise, set the new sort order. 
     else 
     { 
      item.SortOrder = newSortOrder; 
     } 

     // Pass other items into reordering logic. 
     ReOrder(itemsToReorder, oldSortOrder, newSortOrder); 

     // Save all those changes back to the database 
     Context.SaveChanges(); 
    } 
} 

重新排序無效:

public static void ReOrder(IEnumerable<ISortable> list, 
    int oldSortOrder, 
    int newSortOrder) 
{ 
    IEnumerable<ISortable> itemsToReorder; 

    // Pare down the items to just those that will be effected by the move. 
    // New sort order of 0 means the item has been deleted. 
    if (newSortOrder == 0) 
    { 
     itemsToReorder = list.Where(x => x.SortOrder > oldSortOrder); 
    } 
    else 
    { 
     // This is just a long inline if statement. Applies Where() 
     // conditions depending on the old and new sort variables. 
     itemsToReorder = list.Where(x => (oldSortOrder < newSortOrder 
      ? x.SortOrder <= newSortOrder && 
      x.SortOrder > oldSortOrder 
      : x.SortOrder >= newSortOrder && 
      x.SortOrder < oldSortOrder)); 
    } 

    foreach (var i in itemsToReorder) 
    { 
     // Original item was moved down 
     if (newSortOrder != 0 && oldSortOrder < newSortOrder) 
     { 
      i.SortOrder -= 1; 
     } 
     // Original item was moved up 
     else if (newSortOrder != 0 && oldSortOrder > newSortOrder) 
     { 
      i.SortOrder += 1; 
     } // Original item was removed. 
     else 
     { 
      i.SortOrder -= 1; 
     } 
    } 
} 

讓我知道如果你需要一些澄清。我幾乎肯定我沒有充分解釋一切。

+0

非常感謝您的回答。所以我想我的Web API方法只需要兩個參數。正在移動的實體的ID,以及它的新sortIndex。當我去刪除一條記錄時會發生什麼,我會在事後運行相同的邏輯嗎? –

+0

D'oh。我沒有包含刪除部分。我會更新。你基本上發送'itemId'和'newSortOrder = 0'。 –

+0

我完全實現了這個邏輯,出於某種原因,我在重新排序時不斷得到重複。例如,它們中的兩個將具有SortOrder 6.您的排序是否基於零排序?我使我的零基礎,因爲我使用的kendo ui控制看到第一個作爲索引0.此外,我相信我將不得不使用sortOrder -1我的刪除,因爲0在技術上是第一項正確的? –

1
IF OBJECT_ID('tempdb..#Product') IS NOT NULL 
    DROP TABLE #Product 

CREATE TABLE #Product(
    Name VARCHAR(100) NOT NULL 
    ,SortOrder INT NOT NULL 
) 

INSERT INTO #Product (Name, SortOrder) 
VALUES 
('Product1', 0) 
,('Product2', 1) 
,('Product3', 2) 
,('Product4', 3) 
,('Product5', 4) 
,('Product6', 5) 

DECLARE 
    @NewIndex INT 
    ,@OldIndex INT 

SET @OldIndex = 4 --'Product5' 
SET @NewIndex = 2 -- After 'Product2' 

IF @NewIndex < @OldIndex -- Move UP 
    UPDATE #Product 
     SET SortOrder = CASE 
         WHEN SortOrder = @OldIndex THEN @NewIndex 
         ELSE SortOrder + 1 
         END 
    WHERE SortOrder BETWEEN @NewIndex AND @OldIndex; 
ELSE      -- Move DOwn 
    UPDATE #Product 
     SET SortOrder = CASE 
         WHEN SortOrder = @OldIndex THEN @NewIndex 
         ELSE SortOrder - 1 
         END 
    WHERE SortOrder BETWEEN @OldIndex AND @NewIndex; 

SELECT * FROM #Product ORDER BY SortOrder