Les meilleures pratiques pour renuméroter éléments dans une liste? SQL ou C # / VB.NET
-
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
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:
- Point A
- Point B
- Point C
- Article D
- 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.