0

SortOrder整数列を持つデータベーステーブルがあります。テーブルアイテムを追加および編集するためのUIには、整数のドロップダウンリストがあり、ユーザーがこのアイテムを表示するソート順の場所を選択できるようになっています。私の質問は、リスト{1,2,3,4,5、 "last"}と言います。ユーザーが番号を選択した場合、それをアイテムのSortOrder属性にし、次にその'SortOrder'を持つアイテムにします。現在、「SortOrder」が低いアイテムには影響を与えずに、「SortOrder」が高いアイテムと同様に1つ(+ = 1)バンプされます。私は現在、VB.NETとLinqを使用するパブリックモジュール「ユーティリティ」を持っています

新しいMyDataContextとしてのPrivate_db

Public Sub UpdateProductSortOrder(ByVal idx As Integer)

    Dim products = (From p As Product In _db.Products _
        Where p.SortOrder >= idx _
        Select p).ToList()

    For Each p As Product In products
        p.SortOrder += 1
    Next

    _db.SubmitChanges()

End Sub

私がこれをしているので、アイテムを追加するとき、それはうまくいくようです

Protected Overrides Sub AddItem()

    Dim sortOrder As Integer = Int32.Parse(Server.HtmlEncode(ddlNewSortOrder.SelectedValue))

    If (sortOrder >= 1) Then
        Utilities.UpdateProductSortOrder(sortOrder)
    Else
        sortOrder = Utilities.GetNextProductSortOrder()
    End If

    Dim dic As New System.Collections.Specialized.ListDictionary()
    dic.Add("PROD_Description", Server.HtmlEncode(txtNewDescription.Text))
    dic.Add("Abbrev", Server.HtmlEncode(txtNewAbbreviation.Text.ToUpper()))
    dic.Add("SortOrder", sortOrder)

    ProductsGridSource.Insert(dic)

End Sub

しかし、このような既存のアイテムを編集すると、エラーが発生することがあります。

Protected Sub ProductsGridSource_Updating(ByVal sender As Object、ByVal e As System.Web.UI.WebControls.LinqDataSourceUpdateEventArgs)Dim sortOrder As Integer = DirectCast(e.NewObject、Product).SortOrder Utilities.UpdateProductSortOrder(sortOrder)End Sub

これを行うためのより効率的な方法、ベストプラクティス、方法はありますか?アドバイスをいただければ幸いです。

事前に感謝します、サンディエゴの〜ck

4

3 に答える 3

2

編集の秘訣は、すべての番号を更新するのではなく、変更の影響を受ける番号だけを更新することです。1つのアイテムの場合は簡単ですが、一度に複数のアイテムを編集する場合は、SortOrderでソートされたリストにアイテムを保存します。

Dim products = (From p As Product In _db.Products _
        Order By p.SortOrder _
        Select p).ToList()

次に、新しい値に従ってリストを再配置します。

// do a RemoveAt first if you need to move an item
products.InsertAt(sortOrder, dic); 

次に、すべて(または最適化する場合はSortOrderで始まるすべて)に番号を付け直します。

Dim index As Integer = 0
For Each p As Product In products
    p.SortOrder = index
    index += 1
Next

すべての再配置を1つのブロックで実行し、更新を1つのブロックで実行すると、冗長な作業を節約できます。

大規模なレコードセットがある場合、このアプローチはあまりうまく機能しません。その場合、データベースを使用して作業を行うなど、より効率的なアプローチを実行する必要があります。

DECLARE @sortOrder INT
DECLARE @maxSortOrder INT
SET @sortOrder = 5
SET @maxSortOrder = 10
UPDATE Products SET SortOrder = SortOrder + 1 
WHERE SortOrder >= @sortOrder AND SortOrder < @maxSortOrder
于 2009-07-01T17:35:01.980 に答える
1

これはマルチユーザーシステムですか? もしそうなら、それを考慮する必要があります。1 つの方法は、値をインクリメントしている間、データベースをロックすることです。そうしないと、2 人のユーザーが同時にコードを実行すると、データが破損する危険があります。

于 2009-07-01T17:49:25.613 に答える