0

我有一个具有 SortOrder 整数列的数据库表。在用于添加和编辑表格项目的 UI 中,我有一个整数下拉列表,让用户选择他们希望该项目出现在排序顺序中的哪个位置。我的问题是,比如说列表 {1,2,3,4,5,"last"},如果用户选择一个数字,我希望它是 items SortOrder 属性,然后是具有该“SortOrder”的项目当前将增加一个(+ = 1)以及具有较高“SortOrder”的项目,同时不影响具有较低“SortOrder”的项目。我目前有一个使用 VB.NET 和 Linq 的公共模块“实用程序”

私有 _db 作为新的 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

但是在编辑这样的现有项目时,我偶尔会遇到一些错误

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

编辑的技巧是您不想更新每个数字,只更新受更改影响的数字。对于一个项目,这很容易,但如果您一次编辑多个项目,我会将这些项目存储在按 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

如果您在一个块中完成所有重新排列,然后在一个块中进行更新,您将节省一些多余的工作。

如果您有一个大的记录集,这种方法就不会那么好用。在这种情况下,您需要制定更有效的方法,例如使用数据库为您完成工作。

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

编辑项目的 SortOrder 时,您需要原始值和新值。

如果您的列表中有 5 个项目:

  1. 项目 A
  2. B项
  3. 项目 C
  4. 项目 D
  5. 项目 E

如果您想将项目 D 移动到位置 2,那么您只需要增加项目 B 和 C 的 SortOrder 值。

或者,如果您将项目 B 向下移动到位置 4,那么您需要减少项目 C 和 D 的 SortOrder 值。

我会将您的UpdateProductSortOrder方法重命名为InsertProductSortOrder,然后编写一个新方法UpdateProductSortOrder,它需要 2 个参数。

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

当我处理此类问题时,它可以帮助我在纸上写下所有场景并绘制箭头以查看列表中需要进行哪些更改。

于 2009-07-01T17:31:36.307 回答
1

这是多用户系统吗?如果是这样,您需要考虑到这一点。一种方法是在增加值时锁定数据库。否则,如果两个用户同时运行代码,您就有可能获得损坏的数据。

于 2009-07-01T17:49:25.613 回答