2016-08-22 1 views
1

私は製品イメージのリストを画面に表示しています。ユーザーがリゾートにドラッグアンドドロップすると、私はoldIndexとnewIndexにアクセスできます。
製品1 [インデックス:0]
Product2 [度:1]
Product3 [度:2]
Product4 [度:3]
Product5 [索引データベース内のSortOrderの追跡を維持する更新ステートメント

は、以下の私が持っていると言うことができます4]
Product6 [インデックス:5]

、ユーザーがProduct4

前Product2を置くことを決定した私はトラインよgのdb update文がどのようなものになるかを調べる。私は別の投稿を読んでいて、誰かが、newIndex以上のすべての製品のSortOrderフィールドを更新してから、新しい製品をnewIndexに更新する必要があると言いました。
製品1:

これについての何かが私にオフに思われるが、これは次のように私を残して[インデックス:0]
Product2 [インデックス:2]
Product3 [インデックス:3]
Product4 [インデックス: 4]
Product5 [インデックス:5]
Product6 [インデックス:6]

私は本当に私のインデックスが隙間なく完璧な順序での滞在場所これを達成しようとしています。助言がありますか?

+0

これまでEntity Frameworkを使用してこの種の作業を行ってきました。それはSQLにする必要がありますか? –

+0

@BlakeRivell、使用するSQLサーバーを指定してください。 – AlexK

+0

@dansはい私はエンティティフレームワークを使用しています。私はSQL用語で誰かが私に記述するのが最も簡単であると仮定していました。私は剣道のUIソートウィジェットを使用して、リストビューで画像をドラッグ&ドロップし、onChangeは移動したアイテムのoldIndexとnewIndexにアクセスできます。私の計画は、この時点ですべてのレコードのソート順を更新するためにajaxコールを行うことでした。 –

答えて

1

だから私はグラントワークを処理するための空白を書いた。私はSortOrder列を持つ複数の種類のエンティティでこれを行う必要があるため、SortOrder列を含むISortableというインターフェイスを作成しました。 1つのdbテーブルでこれを行う場合は、ISortableのインスタンスをエンティティの名前に置き換えることができます。このボイドの外で発生する必要がどのような

は次のとおりです。

は、あなたの商品の新しいソート順(newSortOrder)を設定し、その後、DBからアイテムを取得し、変数(oldSortOrder)にその古いソート順を保存します変数を、更新したもの以外のすべての項目に設定します(list)。これはまた、データベースから削除されている項目を考慮して、あなたのajax呼び出しでnewSortOrderから0に設定するだけです。

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(); 
    } 
} 

がvoid並べ替え:

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メソッドは2つのパラメータを必要とすると思います。移動されるエンティティのIDとそれに加えて新しいsortIndex。後で同じロジックを実行すると、レコードを削除するとどうなりますか? –

+0

D'oh。私は削除部分を含んでいませんでした。私は更新します。基本的に 'itemId'と' newSortOrder = 0'を送ります。 –

+0

私はこのロジックを正確に実装しましたが、何らかの理由で再注文時に重複しています。たとえば、2つの場合、SortOrderが6になります。並べ替えの順序はゼロに基づいていますか?私は使用している剣道UIコントロールが最初のものをインデックス0と見なすので、私は鉱山をゼロベースにしています。さらに、0は技術的に最初のアイテムなので、削除のためにsortOrder -1を使用する必要があると思いますか? –

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 
関連する問題