2009-07-01 3 views
0

J'ai une table de base de données qui a une colonne entière SortOrder. Dans l'interface utilisateur pour l'ajout et la modification d'éléments de table, j'ai une liste déroulante d'Integer qui permet à l'utilisateur de sélectionner l'endroit où il souhaite que cet élément apparaisse dans le tri. Ma question est, disons la liste, {1,2,3,4,5, "dernier"}, si l'utilisateur choisit un nombre, je veux que ce soit l'attribut SortOrder des éléments, puis l'élément avec ce 'SortOrder' Actuellement, il y en aurait un (+ = 1) ainsi que les objets avec un SortOrder plus élevé sans affecter les objets avec un SortOrder plus bas. J'ai actuellement un module public 'Utilities' en utilisant VB.NET et LINQMeilleure pratique pour renuméroter les éléments d'une liste? SQL ou C#/VB.NET

_db Private 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 ce

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

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

Y at-il un plus effecient peut-être, meilleure pratique, comme je devrais le faire? Tout conseil est apprécié.

Merci à l'avance, ~ ck à San Diego

Répondre

1

L'astuce pour éditer est que vous ne voulez pas mettre à jour chaque nombre, seulement les nombres 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 effectuez la mise à jour dans un blo ck vous économiserez du travail redondant.

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

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

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

Si vous avez 5 articles dans votre liste:

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

Et vous voulez Pour déplacer l'élément D jusqu'à la position 2, il vous suffit d'incrémenter la valeur SortOrder pour les éléments 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 SortOrder pour les articles C et D.

Je renommer votre méthode UpdateProductSortOrder-InsertProductSortOrder puis écrire une nouvelle méthode UpdateProductSortOrder, 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 seront nécessaires.

+0

J'aime cette approche. Oui, je peux voir le problème avec le mien. Je change des valeurs qui ne doivent pas être changées en ajoutant juste 1 à tout. Comment puis-je l'implémenter efficacement avec Linq? – Hcabnettek

1

Est-ce un système multi-utilisateur? Si oui, vous devez prendre cela en considération. Une façon consiste à 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.

Questions connexes