Les meilleures pratiques pour renuméroter éléments dans une liste? SQL ou C # / VB.NET

StackOverflow https://stackoverflow.com/questions/1070328

  •  21-08-2019
  •  | 
  •  

Question

I ai une table de base de données qui a une colonne entière SortOrder. Dans l'interface utilisateur pour ajouter et articles de table d'édition, j'ai une liste déroulante de Integer pour laisser l'utilisateur choisir où dans le sortorder qu'ils aimeraient cet article à paraître. Ma question est, par exemple la liste, {1,2,3,4,5, « dernier »}, si l'utilisateur choisit aa numéro, je veux que ce soit les éléments d'attributs SortOrder, puis l'élément avec ce « SortOrder » serait actuellement être cogné un (+ = 1), ainsi que les éléments avec un plus « SortOrder », sans nuire points avec une faible « SortOrder ». J'ai actuellement un module public 'Utilities' en utilisant VB.NET et LINQ

_db privé 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

Il semble bien fonctionner lorsque l'ajout d'éléments que je fais cela

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

Mais je reçois des erreurs occasionnelles lors de l'édition des articles comme celui-ci exisitng

secondaire protégé ProductsGridSource_Updating (expéditeur de ByVal comme objet, ByVal e comme System.Web.UI.WebControls.LinqDataSourceUpdateEventArgs)         Dim sortOrder As Integer = DirectCast (e.NewObject, Product) .SortOrder         Utilities.UpdateProductSortOrder (sortOrder)     End Sub

Y at-il une façon plus effecient peut-être, les meilleures pratiques, je devrais faire cela? Tout conseil est apprécié.

Merci à l'avance, ~ Ck à San Diego

Était-ce utile?

La solution

L'astuce pour l'édition est que vous ne souhaitez pas mettre à jour tous les numéros, seuls les numéros affectés par le changement. Pour un élément, il peut être facile, mais si vous modifiez plusieurs éléments à la fois, je stocker les articles dans une liste triée par SortOrder:

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

Alors je réorganiser la liste en fonction des nouvelles valeurs:

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

numéroter Ensuite, tout (ou tout en commençant par SortOrder si vous souhaitez optimiser):

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

Si vous faites tout votre réagencement dans un bloc puis faites la mise à jour dans un bloc, vous économiserez des travaux redondants.

Cette approche ne fonctionnera pas si bien si vous avez un grand recordset. Dans ce cas, vous aurez besoin d'élaborer une approche plus efficace, par exemple en utilisant la base de données pour faire votre travail pour vous.

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

Autres conseils

Est-ce un système multi-utilisateurs? Si oui, vous devez prendre cela en considération. Une façon est de verrouiller la base de données pendant que vous incrémentez les valeurs. Sinon, vous risquez d'obtenir des données corrompues si deux utilisateurs exécutent le code en même temps.

Lors de l'édition SortOrder d'un élément, vous aurez besoin à la fois les valeurs d'origine et nouvelles.

Si vous avez 5 éléments dans votre liste:

  1. Point A
  2. Point B
  3. Point C
  4. Article D
  5. Point E

Et vous voulez déplacer Point D jusqu'à la position 2, alors vous aurez seulement besoin d'augmenter la valeur SortOrder des articles B et C.

Ou si vous vous déplacez point B vers le bas à la position 4, alors vous aurez besoin de diminuer la valeur de SortOrder pour les articles C et D.

Je renommer votre méthode pour UpdateProductSortOrder puis écrire InsertProductSortOrder une nouvelle méthode <=>, qui prend 2 arguments.

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

Quand je travaille sur des problèmes comme celui-ci, il me permet d'écrire tous les scénarios sur papier et dessiner des flèches pour voir les changements dans la liste sera nécessaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top