Как лучше всего перенумеровать элементы в списке?SQL или C #/VB.NET

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

  •  21-08-2019
  •  | 
  •  

Вопрос

У меня есть таблица базы данных, в которой есть столбец целых чисел SortOrder.В пользовательском интерфейсе для добавления и редактирования элементов таблицы у меня есть выпадающий список Integer, позволяющий пользователю выбрать, где в сортировщике он хотел бы, чтобы этот элемент отображался.Мой вопрос, скажем, в списке {1,2,3,4,5, "last"}, если пользователь выбирает число, я хочу, чтобы это был атрибут items SortOrder, и тогда элемент с этим 'SortOrder' в данный момент был бы увеличен на единицу (+ = 1), а также элементы с более высоким 'SortOrder', не затрагивая элементы с более низким 'SortOrder'.В настоящее время у меня есть общедоступный модуль "Утилиты", использующий VB.NET и Linq

Private _db Как новый 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

Но я получаю некоторые случайные ошибки при редактировании существующих элементов, подобных этому

Защищенные дочерние продукты: gridsource_updating(обычно отправитель - как объект, обычно он - Как System.Web.UI.WebControls.LinqDataSourceUpdateEventArgs) Затемнить сортировщик как целое число = DirectCast(например,newObject, Product).Сортировщик Служебные программы.UpdateProductSortOrder (сортировщик) Конечный подраздел

Есть ли, может быть, более эффективный, наилучший способ, которым я должен это делать?Любой совет приветствуется.

Заранее спасибо, ~ck в Сан-Диего

Это было полезно?

Решение

Хитрость редактирования заключается в том, что вы не хотите обновлять каждый номер, а только те номера, на которые повлияло изменение.Для одного элемента это может быть легко, но если вы редактируете несколько элементов одновременно, я бы сохранил элементы в списке, отсортированном по 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

Другие советы

Это многопользовательская система?Если это так, вам нужно принять это во внимание.Один из способов - заблокировать базу данных во время увеличения значений.В противном случае вы рискуете получить поврежденные данные, если два пользователя запустят код одновременно.

При редактировании средства сортировки элемента вам понадобятся как исходные, так и новые значения.

Если в вашем списке есть 5 пунктов:

  1. Пункт А
  2. Пункт В
  3. Пункт С
  4. Пункт D
  5. Пункт Е

И вы хотите переместить элемент D в позицию 2, тогда вам нужно будет увеличить значение SortOrder только для элементов B и C.

Или, если вы перемещаете элемент B на позицию 4, вам нужно уменьшить значение SortOrder для элементов C и D.

Я бы переименовал ваш UpdateProductSortOrder способ получения InsertProductSortOrder а затем напишите новый метод UpdateProductSortOrder, который принимает 2 аргумента.

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

Когда я работаю над подобными задачами, это помогает мне выписать все сценарии на бумаге и нарисовать стрелки, чтобы увидеть, какие изменения в списке потребуются.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top