重新编号列表中项目的最佳实践? SQL或C#/ VB.NET

时间:2009-07-01 17:19:11

标签: linq sequence linqdatasource

我有一个具有SortOrder整数列的数据库表。在用于添加和编辑表项的UI中,我有一个Integer下拉列表,让用户选择他们希望此项出现在排序顺序中的位置。我的问题是,比如清单{1,2,3,4,5,“last”},如果用户选择一个数字,我希望它是SortOrder项目的属性,然后是那个带有'SortOrder'的项目目前会增加一个(+ = 1)以及具有更高'SortOrder'的项目,同时不会影响具有较低'SortOrder'的项目。 我目前使用VB.NET和Linq

有一个公共模块'Utilities'

Private _db As New 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

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

受保护的子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)     结束子

是否有更有效的可能,最好的做法,我应该这样做? 任何建议都表示赞赏。

先谢谢, 〜在圣地亚哥

3 个答案:

答案 0 :(得分: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

如果您在一个区块中进行所有重新排列,那么在一个区块中进行更新,您将节省一些冗余工作。

如果你有一个大的记录集,这种方法将无法正常工作。在这种情况下,您需要制定更有效的方法,例如使用数据库为您完成工作。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

如果列表中有5个项目:

  1. 项目A
  2. 项目B
  3. 项目C
  4. 项目D
  5. 项目E
  6. 并且您希望将项目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)
    

    当我处理这样的问题时,它帮助我在纸上写出所有场景并绘制箭头以查看列表中的哪些更改是必要的。