Domanda

Ho una tabella di database che ha una colonna integer SortOrder. Nell'interfaccia utente per l'aggiunta e la modifica degli elementi della tabella, ho una lista di goccia di Integer spento per consentire all'utente di selezionare in quale parte del sortorder vorrebbero questa voce di apparire. La mia domanda è, diciamo la lista, {1,2,3,4,5, "ultimo"}, se l'utente sceglie aa numero, voglio che per essere gli elementi di attributo SortOrder, e quindi la voce con quella 'SortOrder' attualmente sarebbe urtato uno (+ = 1), nonché gli articoli con un più alto 'SortOrder' senza influire articoli con un minore 'SortOrder'. Al momento ho un modulo pubblico 'Utilities' usando VB.NET e Linq

_db privato come nuovo 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

Sembra funzionare bene quando l'aggiunta di elementi come sto facendo questo

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

Ma ho alcuni errori occasionali quando si modificano elementi exisitng come questo

secondario protettivo ProductsGridSource_Updating (ByVal sender As Object, ByVal e come System.Web.UI.WebControls.LinqDataSourceUpdateEventArgs)         Dim sortOrder As Integer = DirectCast (e.NewObject, prodotto) .SortOrder         Utilities.UpdateProductSortOrder (sortOrder)     End Sub

C'è un più efficiente forse, migliori pratiche, così dovrei fare questo? Ogni consiglio è apprezzato.

Grazie in anticipo, ~ Ck a San Diego

È stato utile?

Soluzione

Il trucco per la modifica è che non si vuole aggiornare ogni numero, solo i numeri interessati dalla modifica. Per un oggetto può essere facile, ma se si sta modificando più elementi contemporaneamente avrei memorizzare gli elementi in un elenco ordinato per SortOrder:

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

Poi vorrei riorganizzare la lista in base ai nuovi valori:

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

Poi rinumerazione tutto (o tutto a partire con SortOrder se si desidera ottimizzare):

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

Se non tutto il vostro riordinare in un blocco poi fare l'aggiornamento in un blocco si risparmia qualche lavoro ridondante.

Questo approccio non funziona così bene se si dispone di un ampio set di record. In tal caso sarà necessario elaborare un approccio più efficiente, ad esempio utilizzando il database per fare il vostro lavoro per voi.

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

Altri suggerimenti

Si tratta di un sistema multiutente? Se è così è necessario prendere in considerazione. Un modo è quello di bloccare il database mentre si sta incrementando i valori. In caso contrario, si rischia di ottenere dati corrotti se due utenti eseguono il codice, allo stesso tempo.

Quando si modifica SortOrder di un elemento, è necessario sia i valori originali e nuovi.

Se si dispone di 5 articoli nel proprio elenco:

  1. Voce A
  2. Voce B
  3. Voce C
  4. Voce D
  5. La voce E

E si desidera spostare Voce D fino alla posizione 2, quindi avrete solo bisogno di incrementare il valore per gli elementi SortOrder B e C.

Se si sta spostando Voce B fino alla posizione 4, allora avrete bisogno di diminuire il valore SortOrder per gli elementi C e D.

Vorrei rinominare il metodo UpdateProductSortOrder per InsertProductSortOrder e poi scrivere un nuovo metodo <=>, che prende 2 argomenti.

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

Quando sto lavorando su problemi come questo, mi aiuta a scrivere tutti gli scenari su carta e disegnare frecce per vedere quali cambiamenti nella lista sarà necessario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top