2009-07-01 5 views
0

SortOrder整数列を持つデータベーステーブルがあります。テーブル項目を追加および編集するためのUIには、Integerのドロップダウンリストがあり、ユーザーはこの項目を表示する場所をソート順で選択できます。私の質問は、リスト、{1,2,3,4,5、 "last"}、ユーザーがaa番号を選択した場合、そのアイテムをSortOrder属性にして、その 'SortOrder'現在のところ、「SortOrder」が高い項目だけでなく、「SortOrder」が低い項目には影響を与えない一方で、1つ(+ = 1)の項目だけでなく、 は、私が現在持っているパブリックモジュール「ユーティリティ」を使用してVB.NETやLINQのリストの項目の番号を変更するベストプラクティス? SQLまたはC#/ VB.NET

新MyDataContextが

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 
をやっているとの項目を追加する場合は[OK]を動作するようですとして

プライベート_db

このような既存のアイテムを編集するときに時折エラーが発生する

保護サブ製品GridSource_Updating(ByVal送信者オブジェクト整数= DirectCast(e.NewObject、製品としてSystem.Web.UI.WebControls.LinqDataSourceUpdateEventArgs) 点心はsortOrder).SortOrder Utilities.UpdateProductSortOrder(はsortOrder) End Subのようヴァル電子

は、多分もっとeffecientありますベストプラクティス、私はこれを行う必要がありますか? アドバイスありがとうございます。サンディエゴで事前に

おかげで、 〜CK

答えて

1

編集のトリックは、すべての番号を更新するのではなく、変更の影響を受ける番号のみを更新することです。1つの項目のために、それは簡単にすることができますが、あなたは私がSORTORDERによってソートされたリスト内の項目を格納します一度に複数の項目を編集している場合:

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

は、それから私は、新しい値に応じて、リストを並べ替えるになります。

(あなたが最適化したい場合はSORTORDERで始まるまたはすべて)
// do a RemoveAt first if you need to move an item 
products.InsertAt(sortOrder, dic); 

そして、すべてのものを付け直す:

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

あなたは1つのブロック内のすべてのあなたの並び替えを行う場合は、1つのBLOにアップデートを行いますあなたはいくつかの冗長な作業を省きます。

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

DECLARE @sortOrder INT 
DECLARE @maxSortOrder INT 
SET @sortOrder = 5 
SET @maxSortOrder = 10 
UPDATE Products SET SortOrder = SortOrder + 1 
WHERE SortOrder >= @sortOrder AND SortOrder < @maxSortOrder 
0

アイテムのソート順を編集する場合、元の値と新しい値の両方が必要になります。

あなたは、リスト内の5つの項目がある場合:

  1. 項目
  2. 項目B
  3. 項目C
  4. 項目D
  5. 項目E

をそして、あなたがしたいですアイテムDを位置2まで移動するには、アイテムBのSortOrder値をインクリメントする必要がありますそして、C.

それとも、位置4までの項目Bを移動している場合、あなたは

私は、InsertProductSortOrderとにあなたのUpdateProductSortOrderメソッドの名前を変更します 項目CとD

ためSORTORDER値をデクリメントする必要があります2つの引数をとる新しいメソッド UpdateProductSortOrderを作成します。私はこのような問題に取り組んでいるとき、それは私が紙の上のすべてのシナリオを書き、必要がどうなるか、リスト内の変更を確認するには、矢印を描画するのに役立ちます

Public Sub UpdateProductSortOrder(ByVal originalIdx As Integer, ByVal newIdx As Integer) 

+0

私はこのアプローチが好きです。はい、私は私の問題を見ることができます。私はすべてに1を加えるだけで変更する必要のない値を変更しています。 Linqを使ってこれを効果的に実装するにはどうすればよいですか? – Hcabnettek

1

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

関連する問題